When using virt-v2v-in-place previously, there was no easy way to get
the post-conversion metadata, such as the operating system and
firmware that virt-v2v detected inside the guest.
This adds new, optional '-O output.xml' 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 +++++++++++++-----
tests/Makefile.am | 2 +
tests/test-in-place-xml.sh | 81 ++++++++++++++++++++++++++++++++++++++
5 files changed, 132 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..89e3f5f3 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) \
+ 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..222571b9 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_xml = ref No_output_xml in
+ let set_output_xml_option filename =
+ if filename = "-" then output_xml := Output_xml_to_stdout
+ else output_xml := 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_xml_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_xml = !output_xml 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_xml 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/tests/Makefile.am b/tests/Makefile.am
index 8b9aedc6..9ae28537 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -87,6 +87,7 @@ TESTS = \
test-i-ova.sh \
test-i-vmx.sh \
test-in-place.sh \
+ test-in-place-xml.sh \
test-inspector.sh \
test-it-vddk-io-query.sh \
test-mac.sh \
@@ -255,6 +256,7 @@ EXTRA_DIST += \
test-i-vmx-7.vmx \
test-i-vmx.sh \
test-in-place.sh \
+ test-in-place-xml.sh \
test-inspector.sh \
test-it-vddk-io-query.sh \
test-mac-expected.xml \
diff --git a/tests/test-in-place-xml.sh b/tests/test-in-place-xml.sh
new file mode 100755
index 00000000..2b411e62
--- /dev/null
+++ b/tests/test-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 -O option.
+
+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