copies the OVF.pm and relevant ovf tests from qemu-server.
We need it here, and it uses PVE::Storage already, and since there is no
intermediary package/repository we could put it, it seems fitting in
here.

Put it in a new GuestImport module

Signed-off-by: Dominik Csapak <d.csa...@proxmox.com>
---
 debian/control                                |   2 +
 src/PVE/GuestImport/Makefile                  |   3 +
 src/PVE/GuestImport/OVF.pm                    | 241 ++++++++++++++++++
 src/PVE/Makefile                              |   1 +
 src/PVE/Storage/Makefile                      |   1 +
 src/test/Makefile                             |   5 +-
 src/test/ovf_manifests/Win10-Liz-disk1.vmdk   | Bin 0 -> 65536 bytes
 src/test/ovf_manifests/Win10-Liz.ovf          | 142 +++++++++++
 .../ovf_manifests/Win10-Liz_no_default_ns.ovf | 142 +++++++++++
 .../ovf_manifests/Win_2008_R2_two-disks.ovf   | 145 +++++++++++
 src/test/ovf_manifests/disk1.vmdk             | Bin 0 -> 65536 bytes
 src/test/ovf_manifests/disk2.vmdk             | Bin 0 -> 65536 bytes
 src/test/run_ovf_tests.pl                     |  71 ++++++
 13 files changed, 752 insertions(+), 1 deletion(-)
 create mode 100644 src/PVE/GuestImport/Makefile
 create mode 100644 src/PVE/GuestImport/OVF.pm
 create mode 100644 src/test/ovf_manifests/Win10-Liz-disk1.vmdk
 create mode 100755 src/test/ovf_manifests/Win10-Liz.ovf
 create mode 100755 src/test/ovf_manifests/Win10-Liz_no_default_ns.ovf
 create mode 100755 src/test/ovf_manifests/Win_2008_R2_two-disks.ovf
 create mode 100644 src/test/ovf_manifests/disk1.vmdk
 create mode 100644 src/test/ovf_manifests/disk2.vmdk
 create mode 100755 src/test/run_ovf_tests.pl

diff --git a/debian/control b/debian/control
index d7afa98..dac68ef 100644
--- a/debian/control
+++ b/debian/control
@@ -10,6 +10,7 @@ Build-Depends: debhelper-compat (= 13),
                libpve-common-perl (>= 6.3-2),
                librados2-perl,
                libtest-mockmodule-perl,
+               libxml-libxml-perl,
                lintian,
                perl,
                pve-cluster (>= 5.0-32),
@@ -38,6 +39,7 @@ Depends: ceph-common (>= 12.2~),
          libpve-cluster-perl (>= 8.0.6),
          libpve-common-perl (>= 8.1.1),
          librados2-perl,
+         libxml-libxml-perl,
          lvm2,
          nfs-common,
          proxmox-backup-client (>= 2.1.10~),
diff --git a/src/PVE/GuestImport/Makefile b/src/PVE/GuestImport/Makefile
new file mode 100644
index 0000000..5948384
--- /dev/null
+++ b/src/PVE/GuestImport/Makefile
@@ -0,0 +1,3 @@
+.PHONY: install
+install:
+       install -D -m 0644 OVF.pm ${DESTDIR}${PERLDIR}/PVE/GuestImport/OVF.pm
diff --git a/src/PVE/GuestImport/OVF.pm b/src/PVE/GuestImport/OVF.pm
new file mode 100644
index 0000000..04f8531
--- /dev/null
+++ b/src/PVE/GuestImport/OVF.pm
@@ -0,0 +1,241 @@
+# Open Virtualization Format import routines
+# https://www.dmtf.org/standards/ovf
+package PVE::GuestImport::OVF;
+
+use strict;
+use warnings;
+
+use XML::LibXML;
+use File::Spec;
+use File::Basename;
+use Cwd 'realpath';
+
+use PVE::Tools;
+use PVE::Storage;
+
+# map OVF resources types to descriptive strings
+# this will allow us to explore the xml tree without using magic numbers
+# 
http://schemas.dmtf.org/wbem/cim-html/2/CIM_ResourceAllocationSettingData.html
+my @resources = (
+    { id => 1, dtmf_name => 'Other' },
+    { id => 2, dtmf_name => 'Computer System' },
+    { id => 3, dtmf_name => 'Processor' },
+    { id => 4, dtmf_name => 'Memory' },
+    { id => 5, dtmf_name => 'IDE Controller', pve_type => 'ide' },
+    { id => 6, dtmf_name => 'Parallel SCSI HBA', pve_type => 'scsi' },
+    { id => 7, dtmf_name => 'FC HBA' },
+    { id => 8, dtmf_name => 'iSCSI HBA' },
+    { id => 9, dtmf_name => 'IB HCA' },
+    { id => 10, dtmf_name => 'Ethernet Adapter' },
+    { id => 11, dtmf_name => 'Other Network Adapter' },
+    { id => 12, dtmf_name => 'I/O Slot' },
+    { id => 13, dtmf_name => 'I/O Device' },
+    { id => 14, dtmf_name => 'Floppy Drive' },
+    { id => 15, dtmf_name => 'CD Drive' },
+    { id => 16, dtmf_name => 'DVD drive' },
+    { id => 17, dtmf_name => 'Disk Drive' },
+    { id => 18, dtmf_name => 'Tape Drive' },
+    { id => 19, dtmf_name => 'Storage Extent' },
+    { id => 20, dtmf_name => 'Other storage device', pve_type => 'sata'},
+    { id => 21, dtmf_name => 'Serial port' },
+    { id => 22, dtmf_name => 'Parallel port' },
+    { id => 23, dtmf_name => 'USB Controller' },
+    { id => 24, dtmf_name => 'Graphics controller' },
+    { id => 25, dtmf_name => 'IEEE 1394 Controller' },
+    { id => 26, dtmf_name => 'Partitionable Unit' },
+    { id => 27, dtmf_name => 'Base Partitionable Unit' },
+    { id => 28, dtmf_name => 'Power' },
+    { id => 29, dtmf_name => 'Cooling Capacity' },
+    { id => 30, dtmf_name => 'Ethernet Switch Port' },
+    { id => 31, dtmf_name => 'Logical Disk' },
+    { id => 32, dtmf_name => 'Storage Volume' },
+    { id => 33, dtmf_name => 'Ethernet Connection' },
+    { id => 34, dtmf_name => 'DMTF reserved' },
+    { id => 35, dtmf_name => 'Vendor Reserved'}
+);
+
+sub find_by {
+    my ($key, $param) = @_;
+    foreach my $resource (@resources) {
+       if ($resource->{$key} eq $param) {
+           return ($resource);
+       }
+    }
+    return;
+}
+
+sub dtmf_name_to_id {
+    my ($dtmf_name) = @_;
+    my $found = find_by('dtmf_name', $dtmf_name);
+    if ($found) {
+       return $found->{id};
+    } else {
+       return;
+    }
+}
+
+sub id_to_pve {
+    my ($id) = @_;
+    my $resource = find_by('id', $id);
+    if ($resource) {
+       return $resource->{pve_type};
+    } else {
+       return;
+    }
+}
+
+# returns two references, $qm which holds qm.conf style key/values, and \@disks
+sub parse_ovf {
+    my ($ovf, $debug) = @_;
+
+    my $dom = XML::LibXML->load_xml(location => $ovf, no_blanks => 1);
+
+    # register the xml namespaces in a xpath context object
+    # 'ovf' is the default namespace so it will prepended to each xml element
+    my $xpc = XML::LibXML::XPathContext->new($dom);
+    $xpc->registerNs('ovf', 'http://schemas.dmtf.org/ovf/envelope/1');
+    $xpc->registerNs('rasd', 
'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData');
+    $xpc->registerNs('vssd', 
'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData');
+
+
+    # hash to save qm.conf parameters
+    my $qm;
+
+    #array to save a disk list
+    my @disks;
+
+    # easy xpath
+    # walk down the dom until we find the matching XML element
+    my $xpath_find_name = "/ovf:Envelope/ovf:VirtualSystem/ovf:Name";
+    my $ovf_name = $xpc->findvalue($xpath_find_name);
+
+    if ($ovf_name) {
+       # PVE::QemuServer::confdesc requires a valid DNS name
+       ($qm->{name} = $ovf_name) =~ s/[^a-zA-Z0-9\-\.]//g;
+    } else {
+       warn "warning: unable to parse the VM name in this OVF manifest, 
generating a default value\n";
+    }
+
+    # middle level xpath
+    # element[child] search the elements which have this [child]
+    my $processor_id = dtmf_name_to_id('Processor');
+    my $xpath_find_vcpu_count = 
"/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:ResourceType=${processor_id}]/rasd:VirtualQuantity";
+    $qm->{'cores'} = $xpc->findvalue($xpath_find_vcpu_count);
+
+    my $memory_id = dtmf_name_to_id('Memory');
+    my $xpath_find_memory = 
("/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:ResourceType=${memory_id}]/rasd:VirtualQuantity");
+    $qm->{'memory'} = $xpc->findvalue($xpath_find_memory);
+
+    # middle level xpath
+    # here we expect multiple results, so we do not read the element value with
+    # findvalue() but store multiple elements with findnodes()
+    my $disk_id = dtmf_name_to_id('Disk Drive');
+    my 
$xpath_find_disks="/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:ResourceType=${disk_id}]";
+    my @disk_items = $xpc->findnodes($xpath_find_disks);
+
+    # disks metadata is split in four different xml elements:
+    # * as an Item node of type DiskDrive in the VirtualHardwareSection
+    # * as an Disk node in the DiskSection
+    # * as a File node in the References section
+    # * each Item node also holds a reference to its owning controller
+    #
+    # we iterate over the list of Item nodes of type disk drive, and for each 
item,
+    # find the corresponding Disk node, and File node and owning controller
+    # when all the nodes has been found out, we copy the relevant information 
to
+    # a $pve_disk hash ref, which we push to @disks;
+
+    foreach my $item_node (@disk_items) {
+
+       my $disk_node;
+       my $file_node;
+       my $controller_node;
+       my $pve_disk;
+
+       print "disk item:\n", $item_node->toString(1), "\n" if $debug;
+
+       # from Item, find corresponding Disk node
+       # here the dot means the search should start from the current element 
in dom
+       my $host_resource = $xpc->findvalue('rasd:HostResource', $item_node);
+       my $disk_section_path;
+       my $disk_id;
+
+       # RFC 3986 "2.3.  Unreserved Characters"
+       my $valid_uripath_chars = qr/[[:alnum:]]|[\-\._~]/;
+
+       if ($host_resource =~ 
m|^ovf:/(${valid_uripath_chars}+)/(${valid_uripath_chars}+)$|) {
+           $disk_section_path = $1;
+           $disk_id = $2;
+       } else {
+          warn "invalid host ressource $host_resource, skipping\n";
+          next;
+       }
+       printf "disk section path: $disk_section_path and disk id: $disk_id\n" 
if $debug;
+
+       # tricky xpath
+       # @ means we filter the result query based on a the value of an item 
attribute ( @ = attribute)
+       # @ needs to be escaped to prevent Perl double quote interpolation
+       my $xpath_find_fileref = sprintf("/ovf:Envelope/ovf:DiskSection/\
+ovf:Disk[\@ovf:diskId='%s']/\@ovf:fileRef", $disk_id);
+       my $fileref = $xpc->findvalue($xpath_find_fileref);
+
+       my $valid_url_chars = qr@${valid_uripath_chars}|/@;
+       if (!$fileref || $fileref !~ m/^${valid_url_chars}+$/) {
+           warn "invalid host ressource $host_resource, skipping\n";
+           next;
+       }
+
+       # from Disk Node, find corresponding filepath
+       my $xpath_find_filepath = 
sprintf("/ovf:Envelope/ovf:References/ovf:File[\@ovf:id='%s']/\@ovf:href", 
$fileref);
+       my $filepath = $xpc->findvalue($xpath_find_filepath);
+       if (!$filepath) {
+           warn "invalid file reference $fileref, skipping\n";
+           next;
+       }
+       print "file path: $filepath\n" if $debug;
+
+       # from Item, find owning Controller type
+       my $controller_id = $xpc->findvalue('rasd:Parent', $item_node);
+       my $xpath_find_parent_type = 
sprintf("/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/\
+ovf:Item[rasd:InstanceID='%s']/rasd:ResourceType", $controller_id);
+       my $controller_type = $xpc->findvalue($xpath_find_parent_type);
+       if (!$controller_type) {
+           warn "invalid or missing controller: $controller_type, skipping\n";
+           next;
+       }
+       print "owning controller type: $controller_type\n" if $debug;
+
+       # extract corresponding Controller node details
+       my $adress_on_controller = $xpc->findvalue('rasd:AddressOnParent', 
$item_node);
+       my $pve_disk_address = id_to_pve($controller_type) . 
$adress_on_controller;
+
+       # resolve symlinks and relative path components
+       # and die if the diskimage is not somewhere under the $ovf path
+       my $ovf_dir = realpath(dirname(File::Spec->rel2abs($ovf)));
+       my $backing_file_path = realpath(join ('/', $ovf_dir, $filepath));
+       if ($backing_file_path !~ /^\Q${ovf_dir}\E/) {
+           die "error parsing $filepath, are you using a symlink ?\n";
+       }
+
+       if (!-e $backing_file_path) {
+           die "error parsing $filepath, file seems not to exist at 
$backing_file_path\n";
+       }
+
+       ($backing_file_path) = $backing_file_path =~ m|^(/.*)|; # untaint
+
+       my $virtual_size = PVE::Storage::file_size_info($backing_file_path);
+       die "error parsing $backing_file_path, cannot determine file size\n"
+           if !$virtual_size;
+
+       $pve_disk = {
+           disk_address => $pve_disk_address,
+           backing_file => $backing_file_path,
+           virtual_size => $virtual_size
+       };
+       push @disks, $pve_disk;
+
+    }
+
+    return {qm => $qm, disks => \@disks};
+}
+
+1;
diff --git a/src/PVE/Makefile b/src/PVE/Makefile
index d438804..e15a275 100644
--- a/src/PVE/Makefile
+++ b/src/PVE/Makefile
@@ -6,6 +6,7 @@ install:
        install -D -m 0644 Diskmanage.pm ${DESTDIR}${PERLDIR}/PVE/Diskmanage.pm
        install -D -m 0644 CephConfig.pm ${DESTDIR}${PERLDIR}/PVE/CephConfig.pm
        make -C Storage install
+       make -C GuestImport install
        make -C API2 install
        make -C CLI install
 
diff --git a/src/PVE/Storage/Makefile b/src/PVE/Storage/Makefile
index d5cc942..2daa0da 100644
--- a/src/PVE/Storage/Makefile
+++ b/src/PVE/Storage/Makefile
@@ -14,6 +14,7 @@ SOURCES= \
        PBSPlugin.pm \
        BTRFSPlugin.pm \
        LvmThinPlugin.pm \
+       OVF.pm \
        ESXiPlugin.pm
 
 .PHONY: install
diff --git a/src/test/Makefile b/src/test/Makefile
index c54b10f..12991da 100644
--- a/src/test/Makefile
+++ b/src/test/Makefile
@@ -1,6 +1,6 @@
 all: test
 
-test: test_zfspoolplugin test_disklist test_bwlimit test_plugin
+test: test_zfspoolplugin test_disklist test_bwlimit test_plugin test_ovf
 
 test_zfspoolplugin: run_test_zfspoolplugin.pl
        ./run_test_zfspoolplugin.pl
@@ -13,3 +13,6 @@ test_bwlimit: run_bwlimit_tests.pl
 
 test_plugin: run_plugin_tests.pl
        ./run_plugin_tests.pl
+
+test_ovf: run_ovf_tests.pl
+       ./run_ovf_tests.pl
diff --git a/src/test/ovf_manifests/Win10-Liz-disk1.vmdk 
b/src/test/ovf_manifests/Win10-Liz-disk1.vmdk
new file mode 100644
index 
0000000000000000000000000000000000000000..662354a3d1333a2f6c4364005e53bfe7cd8b9044
GIT binary patch
literal 65536
zcmeIvy>HV%7zbeUF`dK)46s<q+^B&Pi6H|eMIb;zP1VdMK8V$P$u?2T)IS|NNta69
zSXw<No$qu%-}$}AUq|21A0<ihr0Gwa-nQ%QGfCR@wmshsN%A;JUhL<u_T%+U7Sd<o
zW^TMU0^M{}R2S(eR@1Ur*Q@eVF^^#r%c@u{hyC#J%V?Nq?*?z)=UG^1Wn9+n(yx6B
z(=ujtJiA)QVP~;guI5EOE2iV-%_??6=%y!^b+aeU_aA6Z4X2azC>{U!a5_FoJCkDB
zKRozW{5{B<Li)YUBEQ&fJe$RRZCRbA$5|CacQiT<A<uvIHbq(g$>yIY=etVNVcI$B
zY@^?CwTN|j)tg?;i)G&AZFqPqoW(5P2K~XUq>9sqVVe!!?y@Y;)^#k~TefEvd2_XU
z^M@5mfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk4^iOdL%ftb
z5g<T-009C72;3>~`p!f^fB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ
zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U
zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7
z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N
p0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK;Zui`~%h>XmtPp

literal 0
HcmV?d00001

diff --git a/src/test/ovf_manifests/Win10-Liz.ovf 
b/src/test/ovf_manifests/Win10-Liz.ovf
new file mode 100755
index 0000000..bf4b41a
--- /dev/null
+++ b/src/test/ovf_manifests/Win10-Liz.ovf
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Generated by VMware ovftool 4.1.0 (build-2982904), UTC time: 
2017-02-07T13:50:15.265014Z-->
+<Envelope vmw:buildId="build-2982904" 
xmlns="http://schemas.dmtf.org/ovf/envelope/1"; 
xmlns:cim="http://schemas.dmtf.org/wbem/wscim/1/common"; 
xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1"; 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";
 xmlns:vmw="http://www.vmware.com/schema/ovf"; 
xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData";
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
+  <References>
+    <File ovf:href="Win10-Liz-disk1.vmdk" ovf:id="file1" 
ovf:size="9155243008"/>
+  </References>
+  <DiskSection>
+    <Info>Virtual disk information</Info>
+    <Disk ovf:capacity="128" ovf:capacityAllocationUnits="byte * 2^30" 
ovf:diskId="vmdisk1" ovf:fileRef="file1" 
ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized";
 ovf:populatedSize="16798056448"/>
+  </DiskSection>
+  <NetworkSection>
+    <Info>The list of logical networks</Info>
+    <Network ovf:name="bridged">
+      <Description>The bridged network</Description>
+    </Network>
+  </NetworkSection>
+  <VirtualSystem ovf:id="vm">
+    <Info>A virtual machine</Info>
+    <Name>Win10-Liz</Name>
+    <OperatingSystemSection ovf:id="1" vmw:osType="windows9_64Guest">
+      <Info>The kind of installed guest operating system</Info>
+    </OperatingSystemSection>
+    <VirtualHardwareSection>
+      <Info>Virtual hardware requirements</Info>
+      <System>
+        <vssd:ElementName>Virtual Hardware Family</vssd:ElementName>
+        <vssd:InstanceID>0</vssd:InstanceID>
+        <vssd:VirtualSystemIdentifier>Win10-Liz</vssd:VirtualSystemIdentifier>
+        <vssd:VirtualSystemType>vmx-11</vssd:VirtualSystemType>
+      </System>
+      <Item>
+        <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
+        <rasd:Description>Number of Virtual CPUs</rasd:Description>
+        <rasd:ElementName>4 virtual CPU(s)</rasd:ElementName>
+        <rasd:InstanceID>1</rasd:InstanceID>
+        <rasd:ResourceType>3</rasd:ResourceType>
+        <rasd:VirtualQuantity>4</rasd:VirtualQuantity>
+      </Item>
+      <Item>
+        <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>
+        <rasd:Description>Memory Size</rasd:Description>
+        <rasd:ElementName>6144MB of memory</rasd:ElementName>
+        <rasd:InstanceID>2</rasd:InstanceID>
+        <rasd:ResourceType>4</rasd:ResourceType>
+        <rasd:VirtualQuantity>6144</rasd:VirtualQuantity>
+      </Item>
+      <Item>
+        <rasd:Address>0</rasd:Address>
+        <rasd:Description>SATA Controller</rasd:Description>
+        <rasd:ElementName>sataController0</rasd:ElementName>
+        <rasd:InstanceID>3</rasd:InstanceID>
+        <rasd:ResourceSubType>vmware.sata.ahci</rasd:ResourceSubType>
+        <rasd:ResourceType>20</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:Address>0</rasd:Address>
+        <rasd:Description>USB Controller (XHCI)</rasd:Description>
+        <rasd:ElementName>usb3</rasd:ElementName>
+        <rasd:InstanceID>4</rasd:InstanceID>
+        <rasd:ResourceSubType>vmware.usb.xhci</rasd:ResourceSubType>
+        <rasd:ResourceType>23</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:Address>0</rasd:Address>
+        <rasd:Description>USB Controller (EHCI)</rasd:Description>
+        <rasd:ElementName>usb</rasd:ElementName>
+        <rasd:InstanceID>5</rasd:InstanceID>
+        <rasd:ResourceSubType>vmware.usb.ehci</rasd:ResourceSubType>
+        <rasd:ResourceType>23</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="ehciEnabled" 
vmw:value="true"/>
+      </Item>
+      <Item>
+        <rasd:Address>0</rasd:Address>
+        <rasd:Description>SCSI Controller</rasd:Description>
+        <rasd:ElementName>scsiController0</rasd:ElementName>
+        <rasd:InstanceID>6</rasd:InstanceID>
+        <rasd:ResourceSubType>lsilogicsas</rasd:ResourceSubType>
+        <rasd:ResourceType>6</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
+        <rasd:ElementName>serial0</rasd:ElementName>
+        <rasd:InstanceID>7</rasd:InstanceID>
+        <rasd:ResourceType>21</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="yieldOnPoll" 
vmw:value="false"/>
+      </Item>
+      <Item>
+        <rasd:AddressOnParent>0</rasd:AddressOnParent>
+        <rasd:ElementName>disk0</rasd:ElementName>
+        <rasd:HostResource>ovf:/disk/vmdisk1</rasd:HostResource>
+        <rasd:InstanceID>8</rasd:InstanceID>
+        <rasd:Parent>6</rasd:Parent>
+        <rasd:ResourceType>17</rasd:ResourceType>
+      </Item>
+      <Item>
+        <rasd:AddressOnParent>2</rasd:AddressOnParent>
+        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
+        <rasd:Connection>bridged</rasd:Connection>
+        <rasd:Description>E1000e ethernet adapter on 
&quot;bridged&quot;</rasd:Description>
+        <rasd:ElementName>ethernet0</rasd:ElementName>
+        <rasd:InstanceID>9</rasd:InstanceID>
+        <rasd:ResourceSubType>E1000e</rasd:ResourceSubType>
+        <rasd:ResourceType>10</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="wakeOnLanEnabled" 
vmw:value="false"/>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+        <rasd:ElementName>sound</rasd:ElementName>
+        <rasd:InstanceID>10</rasd:InstanceID>
+        <rasd:ResourceSubType>vmware.soundcard.hdaudio</rasd:ResourceSubType>
+        <rasd:ResourceType>1</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+        <rasd:ElementName>video</rasd:ElementName>
+        <rasd:InstanceID>11</rasd:InstanceID>
+        <rasd:ResourceType>24</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="enable3DSupport" 
vmw:value="true"/>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+        <rasd:ElementName>vmci</rasd:ElementName>
+        <rasd:InstanceID>12</rasd:InstanceID>
+        <rasd:ResourceSubType>vmware.vmci</rasd:ResourceSubType>
+        <rasd:ResourceType>1</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AddressOnParent>1</rasd:AddressOnParent>
+        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+        <rasd:ElementName>cdrom0</rasd:ElementName>
+        <rasd:InstanceID>13</rasd:InstanceID>
+        <rasd:Parent>3</rasd:Parent>
+        <rasd:ResourceType>15</rasd:ResourceType>
+      </Item>
+      <vmw:Config ovf:required="false" vmw:key="memoryHotAddEnabled" 
vmw:value="true"/>
+      <vmw:Config ovf:required="false" vmw:key="powerOpInfo.powerOffType" 
vmw:value="soft"/>
+      <vmw:Config ovf:required="false" vmw:key="powerOpInfo.resetType" 
vmw:value="soft"/>
+      <vmw:Config ovf:required="false" vmw:key="powerOpInfo.suspendType" 
vmw:value="soft"/>
+      <vmw:Config ovf:required="false" vmw:key="tools.syncTimeWithHost" 
vmw:value="false"/>
+    </VirtualHardwareSection>
+  </VirtualSystem>
+</Envelope>
diff --git a/src/test/ovf_manifests/Win10-Liz_no_default_ns.ovf 
b/src/test/ovf_manifests/Win10-Liz_no_default_ns.ovf
new file mode 100755
index 0000000..b93540f
--- /dev/null
+++ b/src/test/ovf_manifests/Win10-Liz_no_default_ns.ovf
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Generated by VMware ovftool 4.1.0 (build-2982904), UTC time: 
2017-02-07T13:50:15.265014Z-->
+<Envelope vmw:buildId="build-2982904" 
xmlns="http://schemas.dmtf.org/ovf/envelope/1"; 
xmlns:cim="http://schemas.dmtf.org/wbem/wscim/1/common"; 
xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1"; 
xmlns:vmw="http://www.vmware.com/schema/ovf"; 
xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData";
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
+  <References>
+    <File ovf:href="Win10-Liz-disk1.vmdk" ovf:id="file1" 
ovf:size="9155243008"/>
+  </References>
+  <DiskSection>
+    <Info>Virtual disk information</Info>
+    <Disk ovf:capacity="128" ovf:capacityAllocationUnits="byte * 2^30" 
ovf:diskId="vmdisk1" ovf:fileRef="file1" 
ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized";
 ovf:populatedSize="16798056448"/>
+  </DiskSection>
+  <NetworkSection>
+    <Info>The list of logical networks</Info>
+    <Network ovf:name="bridged">
+      <Description>The bridged network</Description>
+    </Network>
+  </NetworkSection>
+  <VirtualSystem ovf:id="vm">
+    <Info>A virtual machine</Info>
+    <Name>Win10-Liz</Name>
+    <OperatingSystemSection ovf:id="1" vmw:osType="windows9_64Guest">
+      <Info>The kind of installed guest operating system</Info>
+    </OperatingSystemSection>
+    <VirtualHardwareSection>
+      <Info>Virtual hardware requirements</Info>
+      <System>
+        <vssd:ElementName>Virtual Hardware Family</vssd:ElementName>
+        <vssd:InstanceID>0</vssd:InstanceID>
+        <vssd:VirtualSystemIdentifier>Win10-Liz</vssd:VirtualSystemIdentifier>
+        <vssd:VirtualSystemType>vmx-11</vssd:VirtualSystemType>
+      </System>
+      <Item>
+        <rasd:AllocationUnits 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>hertz
 * 10^6</rasd:AllocationUnits>
+        <rasd:Description 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>Number
 of Virtual CPUs</rasd:Description>
+        <rasd:ElementName 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>4
 virtual CPU(s)</rasd:ElementName>
+        <rasd:InstanceID 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>1</rasd:InstanceID>
+        <rasd:ResourceType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>3</rasd:ResourceType>
+        <rasd:VirtualQuantity 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>4</rasd:VirtualQuantity>
+      </Item>
+      <Item>
+        <rasd:AllocationUnits 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>byte
 * 2^20</rasd:AllocationUnits>
+        <rasd:Description 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>Memory
 Size</rasd:Description>
+        <rasd:ElementName 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>6144MB
 of memory</rasd:ElementName>
+        <rasd:InstanceID 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>2</rasd:InstanceID>
+        <rasd:ResourceType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>4</rasd:ResourceType>
+        <rasd:VirtualQuantity 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>6144</rasd:VirtualQuantity>
+      </Item>
+      <Item>
+        <rasd:Address 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>0</rasd:Address>
+        <rasd:Description 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>SATA
 Controller</rasd:Description>
+        <rasd:ElementName 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>sataController0</rasd:ElementName>
+        <rasd:InstanceID 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>3</rasd:InstanceID>
+        <rasd:ResourceSubType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>vmware.sata.ahci</rasd:ResourceSubType>
+        <rasd:ResourceType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>20</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:Address 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>0</rasd:Address>
+        <rasd:Description 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>USB
 Controller (XHCI)</rasd:Description>
+        <rasd:ElementName 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>usb3</rasd:ElementName>
+        <rasd:InstanceID 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>4</rasd:InstanceID>
+        <rasd:ResourceSubType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>vmware.usb.xhci</rasd:ResourceSubType>
+        <rasd:ResourceType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>23</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:Address 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>0</rasd:Address>
+        <rasd:Description 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>USB
 Controller (EHCI)</rasd:Description>
+        <rasd:ElementName 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>usb</rasd:ElementName>
+        <rasd:InstanceID 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>5</rasd:InstanceID>
+        <rasd:ResourceSubType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>vmware.usb.ehci</rasd:ResourceSubType>
+        <rasd:ResourceType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>23</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="ehciEnabled" 
vmw:value="true"/>
+      </Item>
+      <Item>
+        <rasd:Address 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>0</rasd:Address>
+        <rasd:Description 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>SCSI
 Controller</rasd:Description>
+        <rasd:ElementName 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>scsiController0</rasd:ElementName>
+        <rasd:InstanceID 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>6</rasd:InstanceID>
+        <rasd:ResourceSubType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>lsilogicsas</rasd:ResourceSubType>
+        <rasd:ResourceType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>6</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AutomaticAllocation 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>true</rasd:AutomaticAllocation>
+        <rasd:ElementName 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>serial0</rasd:ElementName>
+        <rasd:InstanceID 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>7</rasd:InstanceID>
+        <rasd:ResourceType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>21</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="yieldOnPoll" 
vmw:value="false"/>
+      </Item>
+      <Item>
+        <rasd:AddressOnParent 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";
 >0</rasd:AddressOnParent>
+        <rasd:ElementName 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";
 >disk0</rasd:ElementName>
+        <rasd:HostResource 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";
 >ovf:/disk/vmdisk1</rasd:HostResource>
+        <rasd:InstanceID 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>8</rasd:InstanceID>
+        <rasd:Parent 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>6</rasd:Parent>
+        <rasd:ResourceType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>17</rasd:ResourceType>
+      </Item>
+      <Item>
+        <rasd:AddressOnParent 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>2</rasd:AddressOnParent>
+        <rasd:AutomaticAllocation 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>true</rasd:AutomaticAllocation>
+        <rasd:Connection 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>bridged</rasd:Connection>
+        <rasd:Description 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>E1000e
 ethernet adapter on &quot;bridged&quot;</rasd:Description>
+        <rasd:ElementName 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>ethernet0</rasd:ElementName>
+        <rasd:InstanceID 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>9</rasd:InstanceID>
+        <rasd:ResourceSubType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>E1000e</rasd:ResourceSubType>
+        <rasd:ResourceType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>10</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="wakeOnLanEnabled" 
vmw:value="false"/>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AutomaticAllocation 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>false</rasd:AutomaticAllocation>
+        <rasd:ElementName 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>sound</rasd:ElementName>
+        <rasd:InstanceID 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>10</rasd:InstanceID>
+        <rasd:ResourceSubType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>vmware.soundcard.hdaudio</rasd:ResourceSubType>
+        <rasd:ResourceType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>1</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AutomaticAllocation 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>false</rasd:AutomaticAllocation>
+        <rasd:ElementName 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>video</rasd:ElementName>
+        <rasd:InstanceID 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>11</rasd:InstanceID>
+        <rasd:ResourceType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>24</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="enable3DSupport" 
vmw:value="true"/>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AutomaticAllocation 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>false</rasd:AutomaticAllocation>
+        <rasd:ElementName 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>vmci</rasd:ElementName>
+        <rasd:InstanceID 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>12</rasd:InstanceID>
+        <rasd:ResourceSubType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>vmware.vmci</rasd:ResourceSubType>
+        <rasd:ResourceType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>1</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AddressOnParent 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>1</rasd:AddressOnParent>
+        <rasd:AutomaticAllocation 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>false</rasd:AutomaticAllocation>
+        <rasd:ElementName 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>cdrom0</rasd:ElementName>
+        <rasd:InstanceID 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>13</rasd:InstanceID>
+        <rasd:Parent 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>3</rasd:Parent>
+        <rasd:ResourceType 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";>15</rasd:ResourceType>
+      </Item>
+      <vmw:Config ovf:required="false" vmw:key="memoryHotAddEnabled" 
vmw:value="true"/>
+      <vmw:Config ovf:required="false" vmw:key="powerOpInfo.powerOffType" 
vmw:value="soft"/>
+      <vmw:Config ovf:required="false" vmw:key="powerOpInfo.resetType" 
vmw:value="soft"/>
+      <vmw:Config ovf:required="false" vmw:key="powerOpInfo.suspendType" 
vmw:value="soft"/>
+      <vmw:Config ovf:required="false" vmw:key="tools.syncTimeWithHost" 
vmw:value="false"/>
+    </VirtualHardwareSection>
+  </VirtualSystem>
+</Envelope>
diff --git a/src/test/ovf_manifests/Win_2008_R2_two-disks.ovf 
b/src/test/ovf_manifests/Win_2008_R2_two-disks.ovf
new file mode 100755
index 0000000..a563aab
--- /dev/null
+++ b/src/test/ovf_manifests/Win_2008_R2_two-disks.ovf
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Generated by VMware ovftool 4.1.0 (build-2982904), UTC time: 
2017-02-27T15:09:29.768974Z-->
+<Envelope vmw:buildId="build-2982904" 
xmlns="http://schemas.dmtf.org/ovf/envelope/1"; 
xmlns:cim="http://schemas.dmtf.org/wbem/wscim/1/common"; 
xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1"; 
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";
 xmlns:vmw="http://www.vmware.com/schema/ovf"; 
xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData";
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
+  <References>
+    <File ovf:href="disk1.vmdk" ovf:id="file1" ovf:size="3481968640"/>
+    <File ovf:href="disk2.vmdk" ovf:id="file2" ovf:size="68096"/>
+  </References>
+  <DiskSection>
+    <Info>Virtual disk information</Info>
+    <Disk ovf:capacity="40" ovf:capacityAllocationUnits="byte * 2^30" 
ovf:diskId="vmdisk1" ovf:fileRef="file1" 
ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized";
 ovf:populatedSize="7684882432"/>
+    <Disk ovf:capacity="1" ovf:capacityAllocationUnits="byte * 2^30" 
ovf:diskId="vmdisk2" ovf:fileRef="file2" 
ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized";
 ovf:populatedSize="0"/>
+  </DiskSection>
+  <NetworkSection>
+    <Info>The list of logical networks</Info>
+    <Network ovf:name="bridged">
+      <Description>The bridged network</Description>
+    </Network>
+  </NetworkSection>
+  <VirtualSystem ovf:id="vm">
+    <Info>A virtual machine</Info>
+    <Name>Win_2008-R2x64</Name>
+    <OperatingSystemSection ovf:id="103" vmw:osType="windows7Server64Guest">
+      <Info>The kind of installed guest operating system</Info>
+    </OperatingSystemSection>
+    <VirtualHardwareSection>
+      <Info>Virtual hardware requirements</Info>
+      <System>
+        <vssd:ElementName>Virtual Hardware Family</vssd:ElementName>
+        <vssd:InstanceID>0</vssd:InstanceID>
+        
<vssd:VirtualSystemIdentifier>Win_2008-R2x64</vssd:VirtualSystemIdentifier>
+        <vssd:VirtualSystemType>vmx-11</vssd:VirtualSystemType>
+      </System>
+      <Item>
+        <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
+        <rasd:Description>Number of Virtual CPUs</rasd:Description>
+        <rasd:ElementName>1 virtual CPU(s)</rasd:ElementName>
+        <rasd:InstanceID>1</rasd:InstanceID>
+        <rasd:ResourceType>3</rasd:ResourceType>
+        <rasd:VirtualQuantity>1</rasd:VirtualQuantity>
+      </Item>
+      <Item>
+        <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>
+        <rasd:Description>Memory Size</rasd:Description>
+        <rasd:ElementName>2048MB of memory</rasd:ElementName>
+        <rasd:InstanceID>2</rasd:InstanceID>
+        <rasd:ResourceType>4</rasd:ResourceType>
+        <rasd:VirtualQuantity>2048</rasd:VirtualQuantity>
+      </Item>
+      <Item>
+        <rasd:Address>0</rasd:Address>
+        <rasd:Description>SATA Controller</rasd:Description>
+        <rasd:ElementName>sataController0</rasd:ElementName>
+        <rasd:InstanceID>3</rasd:InstanceID>
+        <rasd:ResourceSubType>vmware.sata.ahci</rasd:ResourceSubType>
+        <rasd:ResourceType>20</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:Address>0</rasd:Address>
+        <rasd:Description>USB Controller (EHCI)</rasd:Description>
+        <rasd:ElementName>usb</rasd:ElementName>
+        <rasd:InstanceID>4</rasd:InstanceID>
+        <rasd:ResourceSubType>vmware.usb.ehci</rasd:ResourceSubType>
+        <rasd:ResourceType>23</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="ehciEnabled" 
vmw:value="true"/>
+      </Item>
+      <Item>
+        <rasd:Address>0</rasd:Address>
+        <rasd:Description>SCSI Controller</rasd:Description>
+        <rasd:ElementName>scsiController0</rasd:ElementName>
+        <rasd:InstanceID>5</rasd:InstanceID>
+        <rasd:ResourceSubType>lsilogicsas</rasd:ResourceSubType>
+        <rasd:ResourceType>6</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
+        <rasd:ElementName>serial0</rasd:ElementName>
+        <rasd:InstanceID>6</rasd:InstanceID>
+        <rasd:ResourceType>21</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="yieldOnPoll" 
vmw:value="false"/>
+      </Item>
+      <Item>
+        <rasd:AddressOnParent>0</rasd:AddressOnParent>
+        <rasd:ElementName>disk0</rasd:ElementName>
+        <rasd:HostResource>ovf:/disk/vmdisk1</rasd:HostResource>
+        <rasd:InstanceID>7</rasd:InstanceID>
+        <rasd:Parent>5</rasd:Parent>
+        <rasd:ResourceType>17</rasd:ResourceType>
+      </Item>
+      <Item>
+        <rasd:AddressOnParent>1</rasd:AddressOnParent>
+        <rasd:ElementName>disk1</rasd:ElementName>
+        <rasd:HostResource>ovf:/disk/vmdisk2</rasd:HostResource>
+        <rasd:InstanceID>8</rasd:InstanceID>
+        <rasd:Parent>5</rasd:Parent>
+        <rasd:ResourceType>17</rasd:ResourceType>
+      </Item>
+      <Item>
+        <rasd:AddressOnParent>2</rasd:AddressOnParent>
+        <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
+        <rasd:Connection>bridged</rasd:Connection>
+        <rasd:Description>E1000 ethernet adapter on 
&quot;bridged&quot;</rasd:Description>
+        <rasd:ElementName>ethernet0</rasd:ElementName>
+        <rasd:InstanceID>9</rasd:InstanceID>
+        <rasd:ResourceSubType>E1000</rasd:ResourceSubType>
+        <rasd:ResourceType>10</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="wakeOnLanEnabled" 
vmw:value="false"/>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+        <rasd:ElementName>sound</rasd:ElementName>
+        <rasd:InstanceID>10</rasd:InstanceID>
+        <rasd:ResourceSubType>vmware.soundcard.hdaudio</rasd:ResourceSubType>
+        <rasd:ResourceType>1</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+        <rasd:ElementName>video</rasd:ElementName>
+        <rasd:InstanceID>11</rasd:InstanceID>
+        <rasd:ResourceType>24</rasd:ResourceType>
+        <vmw:Config ovf:required="false" vmw:key="enable3DSupport" 
vmw:value="true"/>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+        <rasd:ElementName>vmci</rasd:ElementName>
+        <rasd:InstanceID>12</rasd:InstanceID>
+        <rasd:ResourceSubType>vmware.vmci</rasd:ResourceSubType>
+        <rasd:ResourceType>1</rasd:ResourceType>
+      </Item>
+      <Item ovf:required="false">
+        <rasd:AddressOnParent>1</rasd:AddressOnParent>
+        <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+        <rasd:ElementName>cdrom0</rasd:ElementName>
+        <rasd:InstanceID>13</rasd:InstanceID>
+        <rasd:Parent>3</rasd:Parent>
+        <rasd:ResourceType>15</rasd:ResourceType>
+      </Item>
+      <vmw:Config ovf:required="false" vmw:key="cpuHotAddEnabled" 
vmw:value="true"/>
+      <vmw:Config ovf:required="false" vmw:key="memoryHotAddEnabled" 
vmw:value="true"/>
+      <vmw:Config ovf:required="false" vmw:key="powerOpInfo.powerOffType" 
vmw:value="soft"/>
+      <vmw:Config ovf:required="false" vmw:key="powerOpInfo.resetType" 
vmw:value="soft"/>
+      <vmw:Config ovf:required="false" vmw:key="powerOpInfo.suspendType" 
vmw:value="soft"/>
+      <vmw:Config ovf:required="false" vmw:key="tools.syncTimeWithHost" 
vmw:value="false"/>
+    </VirtualHardwareSection>
+  </VirtualSystem>
+</Envelope>
diff --git a/src/test/ovf_manifests/disk1.vmdk 
b/src/test/ovf_manifests/disk1.vmdk
new file mode 100644
index 
0000000000000000000000000000000000000000..8660602343a1a955f9bcf2e6beaed99316dd8167
GIT binary patch
literal 65536
zcmeIvy>HV%7zbeUF`dK)46s<q9ua7|WuUkSgpg2EwX+*viPe0`HWAtSr(-ASlAWQ|
zbJF?F{+-YFKK_yYyn2=-$&0qXY<t)4ch@B8o_Fo_en^t%N%H0}e|H$~AF`0X3J-JR
zqY>z*Sy|tuS*)j3xo%d~*K!`iCRTO1T8@X|%lB-2b2}Q2@{gmi&a1d=x<|K%7N%9q
zn|Qfh$8m45TCV10Gb^W)c4ZxVA@tMpzfJp2S{y#m?iwzx)01@a>+{9rJna?j=ZAyM
zqPW{FznsOxiSi~-&+<BkewLkuP!u<VO<6U6^7*&xtNr=XaoRiS?V{gtwTMl%9Za|L
za#^%_7k)SjXE85!!SM7bspGUQewUqo+Glx@ubWtPwRL-yMO)CL`L7O2fB*pk1PBly
zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pkPg~&a(=JbS1PBlyK!5-N0!ISx
zkM7+PAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+
z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly
zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF
z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk
d1PBlyK!5-N0t5&UAV7cs0RjXF5cr=0{{Ra(Wheju

literal 0
HcmV?d00001

diff --git a/src/test/ovf_manifests/disk2.vmdk 
b/src/test/ovf_manifests/disk2.vmdk
new file mode 100644
index 
0000000000000000000000000000000000000000..c4634513348b392202898374f1c8d2d51d565b27
GIT binary patch
literal 65536
zcmeIvy>HV%7zbeUF`dK)46s<q9#IIDI%J@v2!xPOQ?;`jUy0Rx$u<$$`lr`+(j_}X
ztLLQio&7tX?|uAp{Oj^rk|Zyh{<7(9yX&q=(mrq7>)ntf&y(cMe*SJh-aTX?eH9+&
z#z!O2Psc@dn~q~OEsJ%%D!&!;7&fu2iq&#-6u$l#k8ZBB&%=0f64qH6mv#5(X4k^B
zj9DEow(B_REmq6byr^fzbkeM>VlRY#diJkw-bwTQ2bx{O`BgehC%?a(PtMX_-hBS!
zV6(_?yX6<NxIa-=XX$BH#n2y*PeaJ_>%pcd>%ZCj`_<*{eCa6d4SQYmC$1K;F1Lf}
zc3v#=CU3(J2jMJcc^4cVA0$<rHpO?@@uyvu<=MK9Wm{XjSCKabJ(~aOpacjIAV7cs
z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAn>#W-ahT}R7ZdS0RjXF5Fl_M
z@c!W5Edc@q2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk
z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs
z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ
zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U
eAV7cs0RjXF5FkK+009C72oNAZfB=F2DR2*l=VfOA

literal 0
HcmV?d00001

diff --git a/src/test/run_ovf_tests.pl b/src/test/run_ovf_tests.pl
new file mode 100755
index 0000000..5a80ab2
--- /dev/null
+++ b/src/test/run_ovf_tests.pl
@@ -0,0 +1,71 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use lib qw(..); # prepend .. to @INC so we use the local version of PVE 
packages
+
+use FindBin '$Bin';
+use PVE::GuestImport::OVF;
+use Test::More;
+
+use Data::Dumper;
+
+my $test_manifests = join ('/', $Bin, 'ovf_manifests');
+
+print "parsing ovfs\n";
+
+my $win2008 = eval { 
PVE::GuestImport::OVF::parse_ovf("$test_manifests/Win_2008_R2_two-disks.ovf") };
+if (my $err = $@) {
+    fail('parse win2008');
+    warn("error: $err\n");
+} else {
+    ok('parse win2008');
+}
+my $win10 = eval { 
PVE::GuestImport::OVF::parse_ovf("$test_manifests/Win10-Liz.ovf") };
+if (my $err = $@) {
+    fail('parse win10');
+    warn("error: $err\n");
+} else {
+    ok('parse win10');
+}
+my $win10noNs = eval { 
PVE::GuestImport::OVF::parse_ovf("$test_manifests/Win10-Liz_no_default_ns.ovf") 
};
+if (my $err = $@) {
+    fail("parse win10 no default rasd NS");
+    warn("error: $err\n");
+} else {
+    ok('parse win10 no default rasd NS');
+}
+
+print "testing disks\n";
+
+is($win2008->{disks}->[0]->{disk_address}, 'scsi0', 'multidisk vm has the 
correct first disk controller');
+is($win2008->{disks}->[0]->{backing_file}, "$test_manifests/disk1.vmdk", 
'multidisk vm has the correct first disk backing device');
+is($win2008->{disks}->[0]->{virtual_size}, 2048, 'multidisk vm has the correct 
first disk size');
+
+is($win2008->{disks}->[1]->{disk_address}, 'scsi1', 'multidisk vm has the 
correct second disk controller');
+is($win2008->{disks}->[1]->{backing_file}, "$test_manifests/disk2.vmdk", 
'multidisk vm has the correct second disk backing device');
+is($win2008->{disks}->[1]->{virtual_size}, 2048, 'multidisk vm has the correct 
second disk size');
+
+is($win10->{disks}->[0]->{disk_address}, 'scsi0', 'single disk vm has the 
correct disk controller');
+is($win10->{disks}->[0]->{backing_file}, 
"$test_manifests/Win10-Liz-disk1.vmdk", 'single disk vm has the correct disk 
backing device');
+is($win10->{disks}->[0]->{virtual_size}, 2048, 'single disk vm has the correct 
size');
+
+is($win10noNs->{disks}->[0]->{disk_address}, 'scsi0', 'single disk vm (no 
default rasd NS) has the correct disk controller');
+is($win10noNs->{disks}->[0]->{backing_file}, 
"$test_manifests/Win10-Liz-disk1.vmdk", 'single disk vm (no default rasd NS) 
has the correct disk backing device');
+is($win10noNs->{disks}->[0]->{virtual_size}, 2048, 'single disk vm (no default 
rasd NS) has the correct size');
+
+print "\ntesting vm.conf extraction\n";
+
+is($win2008->{qm}->{name}, 'Win2008-R2x64', 'win2008 VM name is correct');
+is($win2008->{qm}->{memory}, '2048', 'win2008 VM memory is correct');
+is($win2008->{qm}->{cores}, '1', 'win2008 VM cores are correct');
+
+is($win10->{qm}->{name}, 'Win10-Liz', 'win10 VM name is correct');
+is($win10->{qm}->{memory}, '6144', 'win10 VM memory is correct');
+is($win10->{qm}->{cores}, '4', 'win10 VM cores are correct');
+
+is($win10noNs->{qm}->{name}, 'Win10-Liz', 'win10 VM (no default rasd NS) name 
is correct');
+is($win10noNs->{qm}->{memory}, '6144', 'win10 VM (no default rasd NS) memory 
is correct');
+is($win10noNs->{qm}->{cores}, '4', 'win10 VM (no default rasd NS) cores are 
correct');
+
+done_testing();
-- 
2.39.2



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to