Richard W.M. Jones
2014-Oct-18 21:05 UTC
[Libguestfs] GIT: [PATCH 0/5] v2v: Multiple fixes for handling semi-standard OVA files (RHBZ#1152998).
OVA not a real standard. Colour me surprised ...
Richard W.M. Jones
2014-Oct-18 21:05 UTC
[Libguestfs] [PATCH 1/5] mllib: Enhance and rename 'detect_compression' function so it can detect a few more file types.
--- builder/builder.ml | 6 +++++- mllib/common_utils.ml | 29 ++++++++++++++++++++--------- mllib/common_utils.mli | 6 ++---- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/builder/builder.ml b/builder/builder.ml index 5195cfd..121c5fb 100644 --- a/builder/builder.ml +++ b/builder/builder.ml @@ -315,8 +315,12 @@ let main () | None -> [] | Some format -> [`Format, format] in let compression_tag - match detect_compression template with + match detect_file_type template with | `XZ -> [ `XZ, "" ] + | `GZip | `Tar | `Zip -> + eprintf (f_"%s: input file (%s) has an unsupported type\n") + prog template; + exit 1 | `Unknown -> [] in [ `Template, ""; `Filename, template; `Size, Int64.to_string size ] @ format_tag @ compression_tag in diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml index adfad3f..295981c 100644 --- a/mllib/common_utils.ml +++ b/mllib/common_utils.ml @@ -547,17 +547,28 @@ let rm_rf_only_files (g : Guestfs.guestfs) dir List.iter g#rm files ) -(* Detect compression of a file. - * - * Only detects the formats we need in virt-builder so far. - *) -let detect_compression filename +(* Detect type of a file. *) +let detect_file_type filename let chan = open_in filename in - let buf = String.create 6 in - really_input chan buf 0 6; + let get start size + try + seek_in chan start; + let buf = String.create size in + really_input chan buf 0 size; + Some buf + with End_of_file | Invalid_argument _ -> None + in + let ret + if get 0 6 = Some "\2537zXZ\000" then `XZ + else if get 0 4 = Some "PK\003\004" then `Zip + else if get 0 4 = Some "PK\005\006" then `Zip + else if get 0 4 = Some "PK\007\008" then `Zip + else if get 257 6 = Some "ustar\000" then `Tar + else if get 257 8 = Some "ustar\x20\x20\000" then `Tar + else if get 0 2 = Some "\x1f\x8b" then `GZip + else `Unknown in close_in chan; - if buf = "\2537zXZ\000" then `XZ - else `Unknown + ret let is_block_device file try (Unix.stat file).Unix.st_kind = Unix.S_BLK diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli index d78fd70..112648a 100644 --- a/mllib/common_utils.mli +++ b/mllib/common_utils.mli @@ -118,10 +118,8 @@ val rm_rf_only_files : Guestfs.guestfs -> string -> unit XXX Could be faster with a specific API for doing this. *) -val detect_compression : string -> [`Unknown | `XZ] -(** Detect compression of a file. - - XXX Only detects the formats we need in virt-builder so far. *) +val detect_file_type : string -> [`GZip | `Tar | `XZ | `Zip | `Unknown] +(** Detect type of a file. *) val is_block_device : string -> bool val is_char_device : string -> bool -- 2.0.4
Richard W.M. Jones
2014-Oct-18 21:05 UTC
[Libguestfs] [PATCH 2/5] v2v: -i ova: Allow directories and ZIP files to be used as input (RHBZ#1152998).
OVA is not a particularly well-specified format. The specification allows a directory to be an OVA, so enable that. The spec doesn't mention that ZIP can be used in place of tar, but since we have seen these in the wild, allow that too. --- README | 2 ++ configure.ac | 7 +++++++ v2v/input_ova.ml | 44 ++++++++++++++++++++++++++++++++++---------- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/README b/README index b88a67d..30e241a 100644 --- a/README +++ b/README @@ -179,6 +179,8 @@ The full requirements are described below. +--------------+-------------+---+-----------------------------------------+ | gtk2 | | O | Used by virt-p2v user interface. | +--------------+-------------+---+-----------------------------------------+ +| zip, unzip | | O | Used by virt-v2v for OVA files. | ++--------------+-------------+---+-----------------------------------------+ | python-evtx | | O | Used by virt-log to parse Windows | | | | | Event Log files. | +--------------+-------------+---+-----------------------------------------+ diff --git a/configure.ac b/configure.ac index 9196158..b1db2d8 100644 --- a/configure.ac +++ b/configure.ac @@ -720,6 +720,13 @@ if test "x$YACC" = "xyacc"; then AC_MSG_FAILURE([GNU 'bison' is required (yacc won't work).]) fi +dnl zip/unzip, used by virt-v2v +AC_PATH_PROGS([ZIP],[zip],[no]) +AC_DEFINE_UNQUOTED([ZIP],["$ZIP"],[Name of zip program.]) +AM_CONDITIONAL([HAVE_ZIP],[test "x$ZIP" != "xno"]) +AC_PATH_PROGS([UNZIP],[unzip],[no]) +AC_DEFINE_UNQUOTED([UNZIP],["$UNZIP"],[Name of unzip program.]) + dnl Check for QEMU for running binaries on this $host_cpu, fall dnl back to basic 'qemu'. Allow the user to override it. qemu_system="$( diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml index 7088e32..4ad38a0 100644 --- a/v2v/input_ova.ml +++ b/v2v/input_ova.ml @@ -36,13 +36,37 @@ object method as_options = "-i ova " ^ ova method source () - (* Extract ova (tar) file. *) - let cmd = sprintf "tar -xf %s -C %s" (quote ova) (quote tmpdir) in - if verbose then printf "%s\n%!" cmd; - if Sys.command cmd <> 0 then - error (f_"error unpacking %s, see earlier error messages") ova; + (* Extract ova file. *) + let exploded + (* The spec allows a directory to be specified as an ova. This + * is also pretty convenient. + *) + if is_directory ova then ova + else ( + match detect_file_type ova with + | `Tar -> + (* Normal ovas are tar file (not compressed). *) + let cmd = sprintf "tar -xf %s -C %s" (quote ova) (quote tmpdir) in + if verbose then printf "%s\n%!" cmd; + if Sys.command cmd <> 0 then + error (f_"error unpacking %s, see earlier error messages") ova; + tmpdir + | `Zip -> + (* However, although not permitted by the spec, people ship + * zip files as ova too. + *) + let cmd = sprintf "unzip%s -j -d %s %s" + (if verbose then "" else " -q") + (quote tmpdir) (quote ova) in + if verbose then printf "%s\n%!" cmd; + if Sys.command cmd <> 0 then + error (f_"error unpacking %s, see earlier error messages") ova; + tmpdir + | `GZip | `XZ | `Unknown -> + error (f_"%s: unsupported file format") ova + ) in - let files = Sys.readdir tmpdir in + let files = Sys.readdir exploded in let ovf = ref "" in (* Search for the ovf file. *) Array.iter ( @@ -58,13 +82,13 @@ object Array.iter ( fun mf -> if Filename.check_suffix mf ".mf" then ( - let chan = open_in (tmpdir // mf) in + let chan = open_in (exploded // mf) in let rec loop () let line = input_line chan in if Str.string_match rex line 0 then ( let disk = Str.matched_group 1 line in let expected = Str.matched_group 2 line in - let cmd = sprintf "sha1sum %s" (quote (tmpdir // disk)) in + let cmd = sprintf "sha1sum %s" (quote (exploded // disk)) in let out = external_command ~prog cmd in match out with | [] -> @@ -86,7 +110,7 @@ object ) files; (* Parse the ovf file. *) - let xml = read_whole_file (tmpdir // ovf) in + let xml = read_whole_file (exploded // ovf) in let doc = Xml.parse_memory xml in (* Handle namespaces. *) @@ -164,7 +188,7 @@ object let expr = sprintf "/ovf:Envelope/ovf:References/ovf:File[@ovf:id='%s']/@ovf:href" file_ref in let file_name = xpath_to_string expr "" in let disk = { - s_qemu_uri= tmpdir // file_name; + s_qemu_uri= exploded // file_name; s_format = Some "vmdk"; s_target_dev = Some target_dev; } in -- 2.0.4
Richard W.M. Jones
2014-Oct-18 21:05 UTC
[Libguestfs] [PATCH 3/5] v2v: Handle *.vmdk.gz compressed files (RHBZ#1152998).
The OVA spec allows the disk images to be gzipped within the OVA container. --- v2v/input_ova.ml | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml index 4ad38a0..001a579 100644 --- a/v2v/input_ova.ml +++ b/v2v/input_ova.ml @@ -181,14 +181,36 @@ object let file_id = xpath_to_string "rasd:HostResource/text()" "" in let rex = Str.regexp "^ovf:/disk/\\(.*\\)" in if Str.string_match rex file_id 0 then ( + (* Chase the references through to the actual file name. *) let file_id = Str.matched_group 1 file_id in let expr = sprintf "/ovf:Envelope/ovf:DiskSection/ovf:Disk[@ovf:diskId='%s']/@ovf:fileRef" file_id in let file_ref = xpath_to_string expr "" in if file_ref == "" then error (f_"error parsing disk fileRef"); let expr = sprintf "/ovf:Envelope/ovf:References/ovf:File[@ovf:id='%s']/@ovf:href" file_ref in - let file_name = xpath_to_string expr "" in + let filename = xpath_to_string expr "" in + + (* Does the file exist and is it readable? *) + let filename = exploded // filename in + Unix.access filename [Unix.R_OK]; + + (* The spec allows the file to be gzip-compressed, in which case + * we must uncompress it into the tmpdir. + *) + let filename + if detect_file_type filename = `GZip then ( + let new_filename = tmpdir // string_random8 () ^ ".vmdk" in + let cmd + sprintf "zcat %s > %s" (quote filename) (quote new_filename) in + if verbose then printf "%s\n%!" cmd; + if Sys.command cmd <> 0 then + error (f_"error uncompressing %s, see earlier error messages") + filename; + new_filename + ) + else filename in + let disk = { - s_qemu_uri= exploded // file_name; + s_qemu_uri = filename; s_format = Some "vmdk"; s_target_dev = Some target_dev; } in -- 2.0.4
Richard W.M. Jones
2014-Oct-18 21:05 UTC
[Libguestfs] [PATCH 4/5] v2v: -i ova: Add a test for ZIP as a container (RHBZ#1152998).
--- v2v/Makefile.am | 5 +- v2v/test-v2v-i-ova-zip.expected | 15 +++++ v2v/test-v2v-i-ova-zip.ovf | 138 ++++++++++++++++++++++++++++++++++++++++ v2v/test-v2v-i-ova-zip.sh | 77 ++++++++++++++++++++++ 4 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 v2v/test-v2v-i-ova-zip.expected create mode 100644 v2v/test-v2v-i-ova-zip.ovf create mode 100755 v2v/test-v2v-i-ova-zip.sh diff --git a/v2v/Makefile.am b/v2v/Makefile.am index 2092621..e9856fd 100644 --- a/v2v/Makefile.am +++ b/v2v/Makefile.am @@ -25,6 +25,8 @@ EXTRA_DIST = \ test-v2v-i-ova.xml \ test-v2v-i-ova-two-disks.expected \ test-v2v-i-ova-two-disks.ovf \ + test-v2v-i-ova-zip.expected \ + test-v2v-i-ova-zip.ovf \ test-v2v-networks-and-bridges-expected.xml \ test-v2v-networks-and-bridges.xml.in \ virt-v2v.pod @@ -218,7 +220,8 @@ CLEANFILES += stamp-virt-v2v.pod TESTS_ENVIRONMENT = $(top_builddir)/run --test TESTS = \ - test-v2v-i-ova-two-disks.sh + test-v2v-i-ova-two-disks.sh \ + test-v2v-i-ova-zip.sh if ENABLE_APPLIANCE TESTS += \ diff --git a/v2v/test-v2v-i-ova-zip.expected b/v2v/test-v2v-i-ova-zip.expected new file mode 100644 index 0000000..a835f00 --- /dev/null +++ b/v2v/test-v2v-i-ova-zip.expected @@ -0,0 +1,15 @@ +Source guest information (--print-source option): + + source name: 2K8R2EESP1_2_Medium +hypervisor type: vmware + memory: 1073741824 (bytes) + nr vCPUs: 1 + CPU features: + display: +disks: + disk1.vmdk (vmdk) [hda] +removable media: + CD-ROM [hda] +NICs: + Network "Network adapter 1" + diff --git a/v2v/test-v2v-i-ova-zip.ovf b/v2v/test-v2v-i-ova-zip.ovf new file mode 100644 index 0000000..3c685f4 --- /dev/null +++ b/v2v/test-v2v-i-ova-zip.ovf @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Envelope vmw:buildId="build-1750787" 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="7804077568"/> + </References> + <DiskSection> + <Info>Virtual disk information</Info> + <Disk ovf:capacity="50" ovf:capacityAllocationUnits="byte * 2^30" ovf:diskId="vmdisk1" ovf:fileRef="file1" ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" ovf:populatedSize="18975752192"/> + </DiskSection> + <NetworkSection> + <Info>The list of logical networks</Info> + <Network ovf:name="PG-VLAN60"> + <Description>The PG-VLAN60 network</Description> + </Network> + </NetworkSection> + <VirtualSystem ovf:id="2K8R2EESP1_2_Medium"> + <Info>A virtual machine</Info> + <Name>2K8R2EESP1_2_Medium</Name> + <OperatingSystemSection ovf:id="103" vmw:osType="windows7Server64Guest"> + <Info>The kind of installed guest operating system</Info> + <Description>Microsoft Windows Server 2008 R2 (64-bit)</Description> + </OperatingSystemSection> + <VirtualHardwareSection> + <Info>Virtual hardware requirements</Info> + <System> + <vssd:ElementName>Virtual Hardware Family</vssd:ElementName> + <vssd:InstanceID>0</vssd:InstanceID> + <vssd:VirtualSystemIdentifier>2K8R2EESP1_2_Medium</vssd:VirtualSystemIdentifier> + <vssd:VirtualSystemType>vmx-10</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>1024MB of memory</rasd:ElementName> + <rasd:InstanceID>2</rasd:InstanceID> + <rasd:ResourceType>4</rasd:ResourceType> + <rasd:VirtualQuantity>1024</rasd:VirtualQuantity> + </Item> + <Item> + <rasd:Address>0</rasd:Address> + <rasd:Description>SCSI Controller</rasd:Description> + <rasd:ElementName>SCSI controller 0</rasd:ElementName> + <rasd:InstanceID>3</rasd:InstanceID> + <rasd:ResourceSubType>lsilogicsas</rasd:ResourceSubType> + <rasd:ResourceType>6</rasd:ResourceType> + <vmw:Config ovf:required="false" vmw:key="slotInfo.pciSlotNumber" vmw:value="160"/> + </Item> + <Item> + <rasd:Address>1</rasd:Address> + <rasd:Description>IDE Controller</rasd:Description> + <rasd:ElementName>IDE 1</rasd:ElementName> + <rasd:InstanceID>4</rasd:InstanceID> + <rasd:ResourceType>5</rasd:ResourceType> + </Item> + <Item> + <rasd:Address>0</rasd:Address> + <rasd:Description>IDE Controller</rasd:Description> + <rasd:ElementName>IDE 0</rasd:ElementName> + <rasd:InstanceID>5</rasd:InstanceID> + <rasd:ResourceType>5</rasd:ResourceType> + </Item> + <Item ovf:required="false"> + <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation> + <rasd:ElementName>Video card</rasd:ElementName> + <rasd:InstanceID>6</rasd:InstanceID> + <rasd:ResourceType>24</rasd:ResourceType> + <vmw:Config ovf:required="false" vmw:key="enable3DSupport" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="use3dRenderer" vmw:value="automatic"/> + <vmw:Config ovf:required="false" vmw:key="useAutoDetect" vmw:value="true"/> + <vmw:Config ovf:required="false" vmw:key="videoRamSizeInKB" vmw:value="4096"/> + </Item> + <Item ovf:required="false"> + <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation> + <rasd:ElementName>VMCI device</rasd:ElementName> + <rasd:InstanceID>7</rasd:InstanceID> + <rasd:ResourceSubType>vmware.vmci</rasd:ResourceSubType> + <rasd:ResourceType>1</rasd:ResourceType> + <vmw:Config ovf:required="false" vmw:key="allowUnrestrictedCommunication" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="slotInfo.pciSlotNumber" vmw:value="32"/> + </Item> + <Item ovf:required="false"> + <rasd:AddressOnParent>0</rasd:AddressOnParent> + <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation> + <rasd:ElementName>CD/DVD drive 1</rasd:ElementName> + <rasd:InstanceID>8</rasd:InstanceID> + <rasd:Parent>4</rasd:Parent> + <rasd:ResourceSubType>vmware.cdrom.atapi</rasd:ResourceSubType> + <rasd:ResourceType>15</rasd:ResourceType> + </Item> + <Item> + <rasd:AddressOnParent>0</rasd:AddressOnParent> + <rasd:ElementName>Hard disk 1</rasd:ElementName> + <rasd:HostResource>ovf:/disk/vmdisk1</rasd:HostResource> + <rasd:InstanceID>9</rasd:InstanceID> + <rasd:Parent>3</rasd:Parent> + <rasd:ResourceType>17</rasd:ResourceType> + <vmw:Config ovf:required="false" vmw:key="backing.writeThrough" vmw:value="false"/> + </Item> + <Item> + <rasd:AddressOnParent>7</rasd:AddressOnParent> + <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation> + <rasd:Connection>PG-VLAN60</rasd:Connection> + <rasd:Description>E1000 ethernet adapter on "PG-VLAN60"</rasd:Description> + <rasd:ElementName>Network adapter 1</rasd:ElementName> + <rasd:InstanceID>11</rasd:InstanceID> + <rasd:ResourceSubType>E1000</rasd:ResourceSubType> + <rasd:ResourceType>10</rasd:ResourceType> + <vmw:Config ovf:required="false" vmw:key="slotInfo.pciSlotNumber" vmw:value="33"/> + <vmw:Config ovf:required="false" vmw:key="wakeOnLanEnabled" vmw:value="true"/> + </Item> + <vmw:Config ovf:required="false" vmw:key="cpuHotAddEnabled" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="cpuHotRemoveEnabled" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="firmware" vmw:value="bios"/> + <vmw:Config ovf:required="false" vmw:key="virtualICH7MPresent" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="virtualSMCPresent" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="memoryHotAddEnabled" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="nestedHVEnabled" vmw:value="false"/> + <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.standbyAction" vmw:value="checkpoint"/> + <vmw:Config ovf:required="false" vmw:key="powerOpInfo.suspendType" vmw:value="hard"/> + <vmw:Config ovf:required="false" vmw:key="tools.afterPowerOn" vmw:value="true"/> + <vmw:Config ovf:required="false" vmw:key="tools.afterResume" vmw:value="true"/> + <vmw:Config ovf:required="false" vmw:key="tools.beforeGuestShutdown" vmw:value="true"/> + <vmw:Config ovf:required="false" vmw:key="tools.beforeGuestStandby" vmw:value="true"/> + <vmw:Config ovf:required="false" vmw:key="tools.syncTimeWithHost" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="tools.toolsUpgradePolicy" vmw:value="upgradeAtPowerCycle"/> + </VirtualHardwareSection> + </VirtualSystem> +</Envelope> diff --git a/v2v/test-v2v-i-ova-zip.sh b/v2v/test-v2v-i-ova-zip.sh new file mode 100755 index 0000000..cd1e258 --- /dev/null +++ b/v2v/test-v2v-i-ova-zip.sh @@ -0,0 +1,77 @@ +#!/bin/bash - +# libguestfs virt-v2v test script +# Copyright (C) 2014 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Test -i ova option with a zip file. + +unset CDPATH +export LANG=C +set -e + +if [ -n "$SKIP_TEST_V2V_I_OVA_ZIP_SH" ]; then + echo "$0: test skipped because environment variable is set" + exit 77 +fi + +if ! zip --version >/dev/null 2>&1; then + echo "$0: test skipped because 'zip' utility is not available" + exit 77 +fi + +if ! unzip --help >/dev/null 2>&1; then + echo "$0: test skipped because 'unzip' utility is not available" + exit 77 +fi + +if [ "$(guestfish get-backend)" = "uml" ]; then + echo "$0: test skipped because UML backend does not support network" + exit 77 +fi + +virt_tools_data_dir=${VIRT_TOOLS_DATA_DIR:-/usr/share/virt-tools} +if ! test -r $virt_tools_data_dir/rhsrvany.exe; then + echo "$0: test skipped because rhsrvany.exe is not installed" + exit 77 +fi + +d=test-v2v-i-ova-zip.d +rm -rf $d +mkdir $d + +pushd $d + +# Create a phony OVA. This is only a test of source parsing, not +# conversion, so the contents of the disks doesn't matter. +truncate -s 10k disk1.vmdk +sha=`sha1sum disk1.vmdk | awk '{print $1}'` +echo -e "SHA1(disk1.vmdk)=$sha\r" > disk1.mf + +zip -r test ../test-v2v-i-ova-zip.ovf disk1.vmdk disk1.mf +mv test.zip test.ova +popd + +# Run virt-v2v but only as far as the --print-source stage, and +# normalize the output. +$VG virt-v2v --debug-gc --quiet \ + -i ova $d/test.ova \ + --print-source | +sed 's,[^ \t]*\(disk.*.vmdk\),\1,' > $d/source + +# Check the parsed source is what we expect. +diff -u test-v2v-i-ova-zip.expected $d/source + +rm -rf $d -- 2.0.4
Richard W.M. Jones
2014-Oct-18 21:05 UTC
[Libguestfs] [PATCH 5/5] v2v: -i ova: Add a test for *.vmdk.gz compressed files (RHBZ#1152998).
--- v2v/Makefile.am | 3 + v2v/test-v2v-i-ova-gz.expected | 15 +++++ v2v/test-v2v-i-ova-gz.ovf | 138 +++++++++++++++++++++++++++++++++++++++++ v2v/test-v2v-i-ova-gz.sh | 65 +++++++++++++++++++ 4 files changed, 221 insertions(+) create mode 100644 v2v/test-v2v-i-ova-gz.expected create mode 100644 v2v/test-v2v-i-ova-gz.ovf create mode 100755 v2v/test-v2v-i-ova-gz.sh diff --git a/v2v/Makefile.am b/v2v/Makefile.am index e9856fd..c311623 100644 --- a/v2v/Makefile.am +++ b/v2v/Makefile.am @@ -23,6 +23,8 @@ EXTRA_DIST = \ HACKING README.RHEV-M \ test-v2v-i-ova.ovf \ test-v2v-i-ova.xml \ + test-v2v-i-ova-gz.expected \ + test-v2v-i-ova-gz.ovf \ test-v2v-i-ova-two-disks.expected \ test-v2v-i-ova-two-disks.ovf \ test-v2v-i-ova-zip.expected \ @@ -220,6 +222,7 @@ CLEANFILES += stamp-virt-v2v.pod TESTS_ENVIRONMENT = $(top_builddir)/run --test TESTS = \ + test-v2v-i-ova-gz.sh \ test-v2v-i-ova-two-disks.sh \ test-v2v-i-ova-zip.sh diff --git a/v2v/test-v2v-i-ova-gz.expected b/v2v/test-v2v-i-ova-gz.expected new file mode 100644 index 0000000..7631534 --- /dev/null +++ b/v2v/test-v2v-i-ova-gz.expected @@ -0,0 +1,15 @@ +Source guest information (--print-source option): + + source name: 2K8R2EESP1_2_Medium +hypervisor type: vmware + memory: 1073741824 (bytes) + nr vCPUs: 1 + CPU features: + display: +disks: + .vmdk (vmdk) [hda] +removable media: + CD-ROM [hda] +NICs: + Network "Network adapter 1" + diff --git a/v2v/test-v2v-i-ova-gz.ovf b/v2v/test-v2v-i-ova-gz.ovf new file mode 100644 index 0000000..e10ad2b --- /dev/null +++ b/v2v/test-v2v-i-ova-gz.ovf @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Envelope vmw:buildId="build-1750787" 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.gz" ovf:id="file1" ovf:size="7804077568"/> + </References> + <DiskSection> + <Info>Virtual disk information</Info> + <Disk ovf:capacity="50" ovf:capacityAllocationUnits="byte * 2^30" ovf:diskId="vmdisk1" ovf:fileRef="file1" ovf:format="http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" ovf:populatedSize="18975752192"/> + </DiskSection> + <NetworkSection> + <Info>The list of logical networks</Info> + <Network ovf:name="PG-VLAN60"> + <Description>The PG-VLAN60 network</Description> + </Network> + </NetworkSection> + <VirtualSystem ovf:id="2K8R2EESP1_2_Medium"> + <Info>A virtual machine</Info> + <Name>2K8R2EESP1_2_Medium</Name> + <OperatingSystemSection ovf:id="103" vmw:osType="windows7Server64Guest"> + <Info>The kind of installed guest operating system</Info> + <Description>Microsoft Windows Server 2008 R2 (64-bit)</Description> + </OperatingSystemSection> + <VirtualHardwareSection> + <Info>Virtual hardware requirements</Info> + <System> + <vssd:ElementName>Virtual Hardware Family</vssd:ElementName> + <vssd:InstanceID>0</vssd:InstanceID> + <vssd:VirtualSystemIdentifier>2K8R2EESP1_2_Medium</vssd:VirtualSystemIdentifier> + <vssd:VirtualSystemType>vmx-10</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>1024MB of memory</rasd:ElementName> + <rasd:InstanceID>2</rasd:InstanceID> + <rasd:ResourceType>4</rasd:ResourceType> + <rasd:VirtualQuantity>1024</rasd:VirtualQuantity> + </Item> + <Item> + <rasd:Address>0</rasd:Address> + <rasd:Description>SCSI Controller</rasd:Description> + <rasd:ElementName>SCSI controller 0</rasd:ElementName> + <rasd:InstanceID>3</rasd:InstanceID> + <rasd:ResourceSubType>lsilogicsas</rasd:ResourceSubType> + <rasd:ResourceType>6</rasd:ResourceType> + <vmw:Config ovf:required="false" vmw:key="slotInfo.pciSlotNumber" vmw:value="160"/> + </Item> + <Item> + <rasd:Address>1</rasd:Address> + <rasd:Description>IDE Controller</rasd:Description> + <rasd:ElementName>IDE 1</rasd:ElementName> + <rasd:InstanceID>4</rasd:InstanceID> + <rasd:ResourceType>5</rasd:ResourceType> + </Item> + <Item> + <rasd:Address>0</rasd:Address> + <rasd:Description>IDE Controller</rasd:Description> + <rasd:ElementName>IDE 0</rasd:ElementName> + <rasd:InstanceID>5</rasd:InstanceID> + <rasd:ResourceType>5</rasd:ResourceType> + </Item> + <Item ovf:required="false"> + <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation> + <rasd:ElementName>Video card</rasd:ElementName> + <rasd:InstanceID>6</rasd:InstanceID> + <rasd:ResourceType>24</rasd:ResourceType> + <vmw:Config ovf:required="false" vmw:key="enable3DSupport" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="use3dRenderer" vmw:value="automatic"/> + <vmw:Config ovf:required="false" vmw:key="useAutoDetect" vmw:value="true"/> + <vmw:Config ovf:required="false" vmw:key="videoRamSizeInKB" vmw:value="4096"/> + </Item> + <Item ovf:required="false"> + <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation> + <rasd:ElementName>VMCI device</rasd:ElementName> + <rasd:InstanceID>7</rasd:InstanceID> + <rasd:ResourceSubType>vmware.vmci</rasd:ResourceSubType> + <rasd:ResourceType>1</rasd:ResourceType> + <vmw:Config ovf:required="false" vmw:key="allowUnrestrictedCommunication" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="slotInfo.pciSlotNumber" vmw:value="32"/> + </Item> + <Item ovf:required="false"> + <rasd:AddressOnParent>0</rasd:AddressOnParent> + <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation> + <rasd:ElementName>CD/DVD drive 1</rasd:ElementName> + <rasd:InstanceID>8</rasd:InstanceID> + <rasd:Parent>4</rasd:Parent> + <rasd:ResourceSubType>vmware.cdrom.atapi</rasd:ResourceSubType> + <rasd:ResourceType>15</rasd:ResourceType> + </Item> + <Item> + <rasd:AddressOnParent>0</rasd:AddressOnParent> + <rasd:ElementName>Hard disk 1</rasd:ElementName> + <rasd:HostResource>ovf:/disk/vmdisk1</rasd:HostResource> + <rasd:InstanceID>9</rasd:InstanceID> + <rasd:Parent>3</rasd:Parent> + <rasd:ResourceType>17</rasd:ResourceType> + <vmw:Config ovf:required="false" vmw:key="backing.writeThrough" vmw:value="false"/> + </Item> + <Item> + <rasd:AddressOnParent>7</rasd:AddressOnParent> + <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation> + <rasd:Connection>PG-VLAN60</rasd:Connection> + <rasd:Description>E1000 ethernet adapter on "PG-VLAN60"</rasd:Description> + <rasd:ElementName>Network adapter 1</rasd:ElementName> + <rasd:InstanceID>11</rasd:InstanceID> + <rasd:ResourceSubType>E1000</rasd:ResourceSubType> + <rasd:ResourceType>10</rasd:ResourceType> + <vmw:Config ovf:required="false" vmw:key="slotInfo.pciSlotNumber" vmw:value="33"/> + <vmw:Config ovf:required="false" vmw:key="wakeOnLanEnabled" vmw:value="true"/> + </Item> + <vmw:Config ovf:required="false" vmw:key="cpuHotAddEnabled" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="cpuHotRemoveEnabled" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="firmware" vmw:value="bios"/> + <vmw:Config ovf:required="false" vmw:key="virtualICH7MPresent" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="virtualSMCPresent" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="memoryHotAddEnabled" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="nestedHVEnabled" vmw:value="false"/> + <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.standbyAction" vmw:value="checkpoint"/> + <vmw:Config ovf:required="false" vmw:key="powerOpInfo.suspendType" vmw:value="hard"/> + <vmw:Config ovf:required="false" vmw:key="tools.afterPowerOn" vmw:value="true"/> + <vmw:Config ovf:required="false" vmw:key="tools.afterResume" vmw:value="true"/> + <vmw:Config ovf:required="false" vmw:key="tools.beforeGuestShutdown" vmw:value="true"/> + <vmw:Config ovf:required="false" vmw:key="tools.beforeGuestStandby" vmw:value="true"/> + <vmw:Config ovf:required="false" vmw:key="tools.syncTimeWithHost" vmw:value="false"/> + <vmw:Config ovf:required="false" vmw:key="tools.toolsUpgradePolicy" vmw:value="upgradeAtPowerCycle"/> + </VirtualHardwareSection> + </VirtualSystem> +</Envelope> diff --git a/v2v/test-v2v-i-ova-gz.sh b/v2v/test-v2v-i-ova-gz.sh new file mode 100755 index 0000000..6c630fb --- /dev/null +++ b/v2v/test-v2v-i-ova-gz.sh @@ -0,0 +1,65 @@ +#!/bin/bash - +# libguestfs virt-v2v test script +# Copyright (C) 2014 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Test -i ova option with gzip-compressed disks. + +unset CDPATH +export LANG=C +set -e + +if [ -n "$SKIP_TEST_V2V_I_OVA_GZ_SH" ]; then + echo "$0: test skipped because environment variable is set" + exit 77 +fi + +if [ "$(guestfish get-backend)" = "uml" ]; then + echo "$0: test skipped because UML backend does not support network" + exit 77 +fi + +virt_tools_data_dir=${VIRT_TOOLS_DATA_DIR:-/usr/share/virt-tools} +if ! test -r $virt_tools_data_dir/rhsrvany.exe; then + echo "$0: test skipped because rhsrvany.exe is not installed" + exit 77 +fi + +d=test-v2v-i-ova-gz.d +rm -rf $d +mkdir $d + +pushd $d + +truncate -s 10k disk1.vmdk +gzip disk1.vmdk +sha=`sha1sum disk1.vmdk | awk '{print $1}'` +echo -e "SHA1(disk1.vmdk)=$sha\r" > disk1.mf + +tar -cf test.ova ../test-v2v-i-ova-gz.ovf disk1.vmdk.gz disk1.mf +popd + +# Run virt-v2v but only as far as the --print-source stage, and +# normalize the output. +$VG virt-v2v --debug-gc --quiet \ + -i ova $d/test.ova \ + --print-source | +sed 's,[^ \t]*\(\.vmdk\),\1,' > $d/source + +# Check the parsed source is what we expect. +diff -u test-v2v-i-ova-gz.expected $d/source + +rm -rf $d -- 2.0.4
Maybe Matching Threads
- do we have support for xmlns in xml for v2v?
- [PATCH v3 0/3] SUSE VMDP support
- [PATCH v7 0/1] Import directly from OVA tar archive if possible
- [PATCH v6 0/3] Import directly from OVA tar archive if possible
- [PATCH v5 0/3] Import directly from OVA tar archive if possible