When using virt-v2v-in-place previously, there was no easy way to get
the post-conversion information, such as the operating system and
firmware that virt-v2v detected inside the guest.

This adds a new, optional -O output.xml file to write this information
out to a file.  The format is identical to virt-v2v-inspector (and
roughly a superset of virt-inspector).

Fixes: https://issues.redhat.com/browse/RHEL-58032
Thanks: Martin Necas
---
 docs/virt-v2v-in-place.pod     | 18 ++++++++
 in-place/Makefile.am           |  2 +
 in-place/in_place.ml           | 39 +++++++++++-----
 subdir-rules.mk                |  2 +
 tests/Makefile.am              |  2 +
 tests/test-v2v-in-place-xml.sh | 81 ++++++++++++++++++++++++++++++++++
 6 files changed, 134 insertions(+), 10 deletions(-)

diff --git a/docs/virt-v2v-in-place.pod b/docs/virt-v2v-in-place.pod
index c91dc1d3..62e4ef5b 100644
--- a/docs/virt-v2v-in-place.pod
+++ b/docs/virt-v2v-in-place.pod
@@ -7,10 +7,12 @@ virt-v2v-in-place - Convert a guest to use KVM in-place
  virt-v2v-in-place -i disk [other -i* options]
                    [virt-customize options]
                    filename
+                   [-O output.xml]
 
  virt-v2v-in-place -i libvirt|libvirtxml [other -i* options]
                    [virt-customize options]
                    guest
+                   [-O output.xml]
 
 =head1 DESCRIPTION
 
@@ -35,6 +37,14 @@ If the guest has been copied to local libvirt then:
 
  virt-v2v-in-place -i libvirt guest
 
+=head2 Output XML
+
+Optionally use the I<-O> option to write post-conversion metadata
+about the guest to an XML file.  This is in the same format as
+L<virt-v2v-inspector(1)>.  This can be used, for example, to find out
+what operating system and firmware was found inside the guest during
+conversion.
+
 =head2 Exit code
 
 If virt-v2v-in-place fails it will return a non-zero (error) exit
@@ -215,6 +225,14 @@ are mapped to C<out>.
 
 See L<virt-v2v(1)/Networks and bridges>.
 
+=item B<-O> output.xml
+
+=item B<-O ->
+
+If this option is present, write post-conversion metadata about the
+guest to the named XML file, or to stdout if I<-O -> is used.  This is
+in the same format as L<virt-v2v-inspector(1)>.
+
 =item B<--print-source>
 
 Print information about the source guest and stop.  This option is
diff --git a/in-place/Makefile.am b/in-place/Makefile.am
index 2fecb3a7..7db62ef0 100644
--- a/in-place/Makefile.am
+++ b/in-place/Makefile.am
@@ -57,6 +57,7 @@ OCAMLPACKAGES = \
        -I $(top_builddir)/lib \
        -I $(top_builddir)/input \
        -I $(top_builddir)/convert \
+       -I $(top_builddir)/inspector \
        -I $(top_builddir)/common/mlstdutils \
        -I $(top_builddir)/common/mlutils \
        -I $(top_builddir)/common/mlgettext \
@@ -103,6 +104,7 @@ OCAMLLINKFLAGS = \
        mlv2vlib.$(MLARCHIVE) \
        mlconvert.$(MLARCHIVE) \
        mlinput.$(MLARCHIVE) \
+       $(top_builddir)/inspector/create_inspector_xml.$(MLOBJECT) \
        $(LINK_CUSTOM_OCAMLC_ONLY)
 
 virt_v2v_in_place_DEPENDENCIES = \
diff --git a/in-place/in_place.ml b/in-place/in_place.ml
index 8286dbc5..680853ee 100644
--- a/in-place/in_place.ml
+++ b/in-place/in_place.ml
@@ -28,6 +28,12 @@ open Getopt.OptionName
 open Types
 open Utils
 
+open Create_inspector_xml
+
+type output_xml_option =
+  | No_output_xml | Output_xml_to_stdout
+  | Output_xml_to_file of string
+
 (* Matches --mac command line parameters. *)
 let mac_re = PCRE.compile 
"^([[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}):(network|bridge|ip):(.*)$"
 let mac_ip_re = PCRE.compile "^([[:xdigit:]]|:|\\.)+$"
@@ -62,6 +68,13 @@ let rec main () =
   in
 
   let network_map = Networks.create () in
+
+  let output_file = ref No_output_xml in
+  let set_output_file_option filename =
+    if filename = "-" then output_file := Output_xml_to_stdout
+    else output_file := Output_xml_to_file filename
+  in
+
   let static_ips = ref [] in
   let rec add_network str =
     match String.split ":" str with
@@ -177,6 +190,8 @@ let rec main () =
                                     s_"Map network ‘in’ to ‘out’";
     [ L"print-source" ], Getopt.Set print_source,
                                     s_"Print source and stop";
+    [ S 'O' ],       Getopt.String ("output.xml", set_output_file_option),
+                                    s_"Set the output filename";
     [ L"root" ],     Getopt.String ("ask|... ", set_root_choice),
                                     s_"How to choose root filesystem";
   ] in
@@ -235,6 +250,7 @@ read the man page virt-v2v-in-place(1).
   let input_conn = !input_conn in
   let input_mode = !input_mode in
   let print_source = !print_source in
+  let output_file = !output_file in
   let root_choice = !root_choice in
   let static_ips = !static_ips in
 
@@ -252,6 +268,7 @@ read the man page virt-v2v-in-place(1).
       pr "mac-option\n";
       pr "mac-ip-option\n";
       pr "customize-ops\n";
+      pr "output-xml-option\n";
       pr "input:disk\n";
       pr "input:libvirt\n";
       pr "input:libvirtxml\n";
@@ -354,16 +371,18 @@ read the man page virt-v2v-in-place(1).
     ignore (Sys.command cmd)
   );
 
-  (* XXX Should we create target metadata and if so where?
-   *
-   * If the input mode is libvirt, there is an argument for
-   * updating the libvirt XML of the guest.  If the input
-   * mode is disk, maybe we should write <guestname>.xml.
-   *
-   * For the moment we just ignore the output from the
-   * conversion step.
-   *)
-  ignore (inspect, target_meta);
+  (* Write the post-conversion metadata, if asked. *)
+  let chan =
+    match output_file with
+    | No_output_xml -> None
+    | Output_xml_to_stdout -> Some Stdlib.stdout
+    | Output_xml_to_file filename -> Some (open_out filename) in
+  Option.iter (
+    fun chan ->
+      let doc = create_inspector_xml v2vdir inspect target_meta in
+      DOM.doc_to_chan chan doc;
+      Stdlib.flush chan
+  ) chan;
 
   message (f_"Finishing off");
   (* As the last thing, write a file indicating success before
diff --git a/subdir-rules.mk b/subdir-rules.mk
index e969f357..05221b95 100644
--- a/subdir-rules.mk
+++ b/subdir-rules.mk
@@ -47,10 +47,12 @@ $(top_builddir)/generator/generator:
 
 if !HAVE_OCAMLOPT
 MLARCHIVE = cma
+MLOBJECT = cmo
 LINK_CUSTOM_OCAMLC_ONLY = -output-complete-exe
 BEST = c
 else
 MLARCHIVE = cmxa
+MLOBJECT = cmx
 BEST = opt
 endif
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index edc8b910..7f30dcb9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -79,6 +79,7 @@ TESTS = \
        test-v2v-i-disk-parallel.sh \
        test-v2v-i-ova.sh \
        test-v2v-in-place.sh \
+       test-v2v-in-place-xml.sh \
        test-v2v-checksum-good.sh \
        test-v2v-checksum-good-qcow2.sh \
        test-v2v-checksum-bad.sh \
@@ -253,6 +254,7 @@ EXTRA_DIST += \
        test-v2v-i-vmx-6.vmx \
        test-v2v-i-vmx-7.vmx \
        test-v2v-in-place.sh \
+       test-v2v-in-place-xml.sh \
        test-v2v-block-driver.sh \
        test-v2v-inspector.sh \
        test-v2v-it-vddk-io-query.sh \
diff --git a/tests/test-v2v-in-place-xml.sh b/tests/test-v2v-in-place-xml.sh
new file mode 100755
index 00000000..30969ec5
--- /dev/null
+++ b/tests/test-v2v-in-place-xml.sh
@@ -0,0 +1,81 @@
+#!/bin/bash -
+# libguestfs virt-v2v test script
+# Copyright (C) 2014 Red Hat Inc.
+# Copyright (C) 2015 Parallels IP Holdings GmbH.
+#
+# 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 virt-v2v-in-place.
+
+unset CDPATH
+export LANG=C
+set -e
+
+source ./functions.sh
+set -e
+set -x
+
+skip_if_skipped
+requires test -f ../test-data/phony-guests/windows.img
+
+img_base="$abs_top_builddir/test-data/phony-guests/windows.img"
+
+export VIRT_TOOLS_DATA_DIR="$srcdir/../test-data/fake-virt-tools"
+export VIRTIO_WIN="$srcdir/../test-data/fake-virtio-win"
+
+d=$PWD/test-v2v-in-place-xml.d
+rm -rf $d
+cleanup_fn rm -r $d
+mkdir $d
+
+img="$d/test.qcow2"
+qemu-img convert -f raw $img_base -O qcow2 $img
+
+out="$d/out.xml"
+
+libvirt_xml="$d/test.xml"
+rm -f $libvirt_xml
+n=windows
+cat > $libvirt_xml <<EOF
+<node>
+  <domain type='test'>
+    <name>$n</name>
+    <memory>1048576</memory>
+    <os>
+      <type>hvm</type>
+      <boot dev='hd'/>
+    </os>
+    <devices>
+      <disk type='file' device='disk'>
+        <driver name='qemu' type='qcow2'/>
+        <source file='$img'/>
+        <target dev='vda' bus='virtio'/>
+      </disk>
+    </devices>
+  </domain>
+</node>
+EOF
+
+$VG virt-v2v-in-place --debug-gc -i libvirt -ic "test://$libvirt_xml" \
+    $n -O $out
+cat $out
+
+# Expect certain elements to be present.
+grep '^<v2v-inspection' $out
+grep '<program>virt-v2v-inspector</program>' $out
+grep '<disks>' $out
+grep "<disk index='0'>" $out
+grep '<distro>windows</distro>' $out
+grep '<osinfo>win2k22</osinfo>' $out
-- 
2.47.0
_______________________________________________
Libguestfs mailing list -- guestfs@lists.libguestfs.org
To unsubscribe send an email to guestfs-le...@lists.libguestfs.org

Reply via email to