mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
v2v: Add -o qemu output mode and --qemu-boot flag.
This lets you write a shell script that runs the guest under qemu. Specifying the --qemu-boot flag also boots the guest after conversion.
This commit is contained in:
@@ -102,6 +102,7 @@ v2v/output_glance.ml
|
||||
v2v/output_libvirt.ml
|
||||
v2v/output_local.ml
|
||||
v2v/output_null.ml
|
||||
v2v/output_qemu.ml
|
||||
v2v/output_rhev.ml
|
||||
v2v/output_vdsm.ml
|
||||
v2v/stringMap.ml
|
||||
|
||||
@@ -47,6 +47,7 @@ SOURCES_MLI = \
|
||||
output_libvirt.mli \
|
||||
output_local.mli \
|
||||
output_null.mli \
|
||||
output_qemu.mli \
|
||||
output_rhev.mli \
|
||||
output_vdsm.mli \
|
||||
stringMap.mli \
|
||||
@@ -77,6 +78,7 @@ SOURCES_ML = \
|
||||
output_glance.ml \
|
||||
output_libvirt.ml \
|
||||
output_local.ml \
|
||||
output_qemu.ml \
|
||||
output_rhev.ml \
|
||||
output_vdsm.ml \
|
||||
cmdline.ml \
|
||||
@@ -222,6 +224,7 @@ TESTS = \
|
||||
test-v2v-o-glance.sh \
|
||||
test-v2v-o-libvirt.sh \
|
||||
test-v2v-o-null.sh \
|
||||
test-v2v-o-qemu.sh \
|
||||
test-v2v-o-rhev.sh \
|
||||
test-v2v-o-vdsm-options.sh \
|
||||
test-v2v-of-option.sh \
|
||||
|
||||
@@ -42,6 +42,7 @@ let parse_cmdline () =
|
||||
let output_name = ref "" in
|
||||
let output_storage = ref "" in
|
||||
let print_source = ref false in
|
||||
let qemu_boot = ref false in
|
||||
let quiet = ref false in
|
||||
let vdsm_image_uuid = ref "" in
|
||||
let vdsm_vm_uuid = ref "" in
|
||||
@@ -85,6 +86,7 @@ let parse_cmdline () =
|
||||
| "disk" | "local" -> output_mode := `Local
|
||||
| "null" -> output_mode := `Null
|
||||
| "ovirt" | "rhev" -> output_mode := `RHEV
|
||||
| "qemu" -> output_mode := `QEmu
|
||||
| "vdsm" -> output_mode := `VDSM
|
||||
| s ->
|
||||
error (f_"unknown -o option: %s") s
|
||||
@@ -135,6 +137,7 @@ let parse_cmdline () =
|
||||
"-on", Arg.Set_string output_name, "name " ^ s_"Rename guest when converting";
|
||||
"-os", Arg.Set_string output_storage, "storage " ^ s_"Set output storage location";
|
||||
"--print-source", Arg.Set print_source, " " ^ s_"Print source and stop";
|
||||
"--qemu-boot", Arg.Set qemu_boot, " " ^ s_"Boot in qemu (-o qemu only)";
|
||||
"-q", Arg.Set quiet, " " ^ s_"Quiet output";
|
||||
"--quiet", Arg.Set quiet, ditto;
|
||||
"--root", Arg.String set_root_choice,"ask|... " ^ s_"How to choose root filesystem";
|
||||
@@ -194,6 +197,7 @@ read the man page virt-v2v(1).
|
||||
let output_name = match !output_name with "" -> None | s -> Some s in
|
||||
let output_storage = !output_storage in
|
||||
let print_source = !print_source in
|
||||
let qemu_boot = !qemu_boot in
|
||||
let quiet = !quiet in
|
||||
let root_choice = !root_choice in
|
||||
let vdsm_image_uuid = !vdsm_image_uuid in
|
||||
@@ -271,6 +275,8 @@ read the man page virt-v2v(1).
|
||||
error (f_"-o glance: -oc option cannot be used in this output mode");
|
||||
if output_storage <> "" then
|
||||
error (f_"-o glance: -os option cannot be used in this output mode");
|
||||
if qemu_boot then
|
||||
error (f_"-o glance: --qemu-boot option cannot be used in this output mode");
|
||||
if vmtype <> None then
|
||||
error (f_"--vmtype option cannot be used with '-o glance'");
|
||||
if not do_copy then
|
||||
@@ -281,6 +287,8 @@ read the man page virt-v2v(1).
|
||||
| `Libvirt ->
|
||||
let output_storage =
|
||||
if output_storage = "" then "default" else output_storage in
|
||||
if qemu_boot then
|
||||
error (f_"-o libvirt: --qemu-boot option cannot be used in this output mode");
|
||||
if vmtype <> None then
|
||||
error (f_"--vmtype option cannot be used with '-o libvirt'");
|
||||
if not do_copy then
|
||||
@@ -293,6 +301,8 @@ read the man page virt-v2v(1).
|
||||
if not (is_directory output_storage) then
|
||||
error (f_"-os %s: output directory does not exist or is not a directory")
|
||||
output_storage;
|
||||
if qemu_boot then
|
||||
error (f_"-o local: --qemu-boot option cannot be used in this output mode");
|
||||
if vmtype <> None then
|
||||
error (f_"--vmtype option cannot be used with '-o local'");
|
||||
Output_local.output_local verbose output_storage
|
||||
@@ -302,18 +312,30 @@ read the man page virt-v2v(1).
|
||||
error (f_"-o null: -oc option cannot be used in this output mode");
|
||||
if output_storage <> "" then
|
||||
error (f_"-o null: -os option cannot be used in this output mode");
|
||||
if qemu_boot then
|
||||
error (f_"-o null: --qemu-boot option cannot be used in this output mode");
|
||||
if vmtype <> None then
|
||||
error (f_"--vmtype option cannot be used with '-o null'");
|
||||
Output_null.output_null verbose
|
||||
|
||||
| `QEmu ->
|
||||
if not (is_directory output_storage) then
|
||||
error (f_"-os %s: output directory does not exist or is not a directory")
|
||||
output_storage;
|
||||
Output_qemu.output_qemu verbose output_storage qemu_boot
|
||||
|
||||
| `RHEV ->
|
||||
if output_storage = "" then
|
||||
error (f_"-o rhev: output storage was not specified, use '-os'");
|
||||
if qemu_boot then
|
||||
error (f_"-o rhev: --qemu-boot option cannot be used in this output mode");
|
||||
Output_rhev.output_rhev verbose output_storage vmtype output_alloc
|
||||
|
||||
| `VDSM ->
|
||||
if output_storage = "" then
|
||||
error (f_"-o vdsm: output storage was not specified, use '-os'");
|
||||
if qemu_boot then
|
||||
error (f_"-o vdsm: --qemu-boot option cannot be used in this output mode");
|
||||
if vdsm_image_uuid = "" || vdsm_vm_uuid = "" then
|
||||
error (f_"-o vdsm: either --vdsm-image-uuid or --vdsm-vm-uuid was not specified");
|
||||
let vdsm_params = {
|
||||
|
||||
103
v2v/output_qemu.ml
Normal file
103
v2v/output_qemu.ml
Normal file
@@ -0,0 +1,103 @@
|
||||
(* virt-v2v
|
||||
* Copyright (C) 2009-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.
|
||||
*)
|
||||
|
||||
open Printf
|
||||
|
||||
open Common_gettext.Gettext
|
||||
open Common_utils
|
||||
|
||||
open Types
|
||||
open Utils
|
||||
|
||||
class output_qemu verbose dir qemu_boot =
|
||||
object
|
||||
inherit output verbose
|
||||
|
||||
method as_options =
|
||||
sprintf "-o qemu -os %s%s" dir (if qemu_boot then " --qemu-boot" else "")
|
||||
|
||||
method prepare_targets source targets =
|
||||
List.map (
|
||||
fun t ->
|
||||
let target_file = dir // source.s_name ^ "-" ^ t.target_overlay.ov_sd in
|
||||
{ t with target_file = target_file }
|
||||
) targets
|
||||
|
||||
method create_metadata source targets guestcaps _ =
|
||||
let name = source.s_name in
|
||||
let file = dir // name ^ ".sh" in
|
||||
|
||||
let chan = open_out file in
|
||||
|
||||
let fpf fs = fprintf chan fs in
|
||||
fpf "#!/bin/sh -\n";
|
||||
fpf "\n";
|
||||
fpf "qemu-system-%s \\\n" guestcaps.gcaps_arch;
|
||||
fpf "\t-no-user-config -nodefaults \\\n";
|
||||
fpf "\t-name %s \\\n" (quote source.s_name);
|
||||
fpf "\t-machine accel=kvm:tcg \\\n";
|
||||
fpf "\t-m %Ld \\\n" (source.s_memory /^ 1024L /^ 1024L);
|
||||
if source.s_vcpu > 1 then
|
||||
fpf "\t-smp %d \\\n" source.s_vcpu;
|
||||
|
||||
let block_bus =
|
||||
match guestcaps.gcaps_block_bus with
|
||||
| Virtio_blk -> "virtio"
|
||||
| IDE -> "ide" in
|
||||
List.iter (
|
||||
fun t ->
|
||||
let qemu_quoted_filename = replace_str t.target_file "," ",," in
|
||||
let drive_param =
|
||||
sprintf "file=%s,format=%s,if=%s"
|
||||
qemu_quoted_filename t.target_format block_bus in
|
||||
fpf "\t-drive %s\\\n" (quote drive_param)
|
||||
) targets;
|
||||
|
||||
let net_bus =
|
||||
match guestcaps.gcaps_net_bus with
|
||||
| Virtio_net -> "virtio-net-pci"
|
||||
| E1000 -> "e1000"
|
||||
| RTL8139 -> "rtl8139" in
|
||||
List.iteri (
|
||||
fun i nic ->
|
||||
fpf "\t-netdev user,id=net%d \\\n" i;
|
||||
fpf "\t-device %s,netdev=net%d%s \\\n"
|
||||
net_bus i (match nic.s_mac with None -> "" | Some mac -> ",mac=" ^ mac)
|
||||
) source.s_nics;
|
||||
|
||||
(* Add a serial console. *)
|
||||
fpf "\t-serial stdio\n";
|
||||
|
||||
(* XXX Missing:
|
||||
* - removable devices
|
||||
* - display
|
||||
*)
|
||||
|
||||
close_out chan;
|
||||
|
||||
Unix.chmod file 0o755;
|
||||
|
||||
(* If --qemu-boot option was specified then we should boot the guest. *)
|
||||
if qemu_boot then (
|
||||
let cmd = sprintf "%s &" (quote file) in
|
||||
ignore (Sys.command cmd)
|
||||
)
|
||||
end
|
||||
|
||||
let output_qemu = new output_qemu
|
||||
let () = Modules_list.register_output_module "qemu"
|
||||
24
v2v/output_qemu.mli
Normal file
24
v2v/output_qemu.mli
Normal file
@@ -0,0 +1,24 @@
|
||||
(* virt-v2v
|
||||
* Copyright (C) 2009-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.
|
||||
*)
|
||||
|
||||
(** [-o qemu] target. *)
|
||||
|
||||
val output_qemu : bool -> string -> bool -> Types.output
|
||||
(** [output_qemu verbose filename qemu_boot] creates and returns a new
|
||||
{!Types.output} object specialized for writing output to local
|
||||
files with a qemu script to start the guest locally. *)
|
||||
64
v2v/test-v2v-o-qemu.sh
Executable file
64
v2v/test-v2v-o-qemu.sh
Executable file
@@ -0,0 +1,64 @@
|
||||
#!/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 -o qemu.
|
||||
|
||||
unset CDPATH
|
||||
export LANG=C
|
||||
set -e
|
||||
|
||||
if [ -n "$SKIP_TEST_V2V_O_QEMU_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
|
||||
|
||||
abs_top_builddir="$(cd ..; pwd)"
|
||||
libvirt_uri="test://$abs_top_builddir/tests/guests/guests.xml"
|
||||
|
||||
f=../tests/guests/windows.img
|
||||
if ! test -f $f || ! test -s $f; then
|
||||
echo "$0: test skipped because phony Windows image was not created"
|
||||
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-o-qemu.d
|
||||
rm -rf $d
|
||||
mkdir $d
|
||||
|
||||
$VG virt-v2v --debug-gc \
|
||||
-i libvirt -ic "$libvirt_uri" windows \
|
||||
-o qemu -os $d
|
||||
|
||||
# Test that the disk was created.
|
||||
test -f $d/windows-sda
|
||||
|
||||
# Test that the script was created and is executable.
|
||||
test -x $d/windows.sh
|
||||
|
||||
rm -r $d
|
||||
@@ -31,12 +31,12 @@ libguestfs E<ge> 1.28.
|
||||
=head1 INPUT AND OUTPUT MODES
|
||||
|
||||
┌────────────┐ ┌─────────▶ -o null
|
||||
-i disk ───────────┐ │ │ │┌───────▶ -o local
|
||||
-i ova ─────────┐ └──▶ │ virt-v2v │ ─┘│
|
||||
└────▶ │ conversion │ ──┘┌────────────┐
|
||||
ESX ──▶┌────────────┐ │ server │ ───▶ -o libvirt │─▶ KVM
|
||||
Xen ──▶│ -i libvirt ──▶ │ │ │ (default) │
|
||||
... ──▶│ (default) │ │ │ ──┐└────────────┘
|
||||
-i disk ───────────┐ │ │ ─┘┌───────▶ -o local
|
||||
-i ova ─────────┐ └──▶ │ virt-v2v │ ──┘┌───────▶ -o qemu
|
||||
└────▶ │ conversion │ ───┘┌────────────┐
|
||||
ESX ──▶┌────────────┐ │ server │ ────▶ -o libvirt │─▶ KVM
|
||||
Xen ──▶│ -i libvirt ──▶ │ │ │ (default) │
|
||||
... ──▶│ (default) │ │ │ ──┐ └────────────┘
|
||||
└────────────┘ │ │ ─┐└──────▶ -o glance
|
||||
-i libvirtxml ────────▶ │ │ ┐└─────────▶ -o rhev
|
||||
└────────────┘ └──────────▶ -o vdsm
|
||||
@@ -64,7 +64,11 @@ I<-o libvirt> is used for writing to any libvirt target. Libvirt can
|
||||
connect to local or remote KVM hypervisors. The I<-oc> option selects
|
||||
the precise libvirt target.
|
||||
|
||||
I<-o local> is used to write to a local disk image (mainly for testing).
|
||||
I<-o local> is used to write to a local disk image with a local
|
||||
libvirt configuration file (mainly for testing).
|
||||
|
||||
I<-o qemu> writes to a local disk image with a shell script for
|
||||
booting the guest directly in qemu (mainly for testing).
|
||||
|
||||
I<-o rhev> is used to write to a RHEV-M / oVirt target. I<-o vdsm>
|
||||
is only used when virt-v2v runs under VDSM control.
|
||||
@@ -134,6 +138,11 @@ Since C<guest-domain.xml> contains the path(s) to the guest disk
|
||||
image(s) you do not need to specify the name of the disk image on the
|
||||
command line.
|
||||
|
||||
To convert a local disk image and immediately boot it in local
|
||||
qemu, do:
|
||||
|
||||
virt-v2v -i disk disk.img -o qemu -os /var/tmp --qemu-boot
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over 4
|
||||
@@ -293,6 +302,17 @@ written.
|
||||
|
||||
This is the same as I<-o rhev>.
|
||||
|
||||
=item B<-o qemu>
|
||||
|
||||
Set the output method to I<qemu>.
|
||||
|
||||
This is similar to I<-o local>, except that a shell script is written
|
||||
which you can use to boot the guest in qemu. The converted disks and
|
||||
shell script are written to the directory specified by I<-os>.
|
||||
|
||||
When using this output mode, you can also specify the I<--qemu-boot>
|
||||
option which boots the guest under qemu immediately.
|
||||
|
||||
=item B<-o rhev>
|
||||
|
||||
Set the output method to I<rhev>.
|
||||
@@ -341,7 +361,8 @@ The location of the storage for the converted guest.
|
||||
For I<-o libvirt>, this is a libvirt directory pool
|
||||
(see S<C<virsh pool-list>>) or pool UUID.
|
||||
|
||||
For I<-o local>, this is a directory name. The directory must exist.
|
||||
For I<-o local> and I<-o qemu>, this is a directory name. The
|
||||
directory must exist.
|
||||
|
||||
For I<-o rhev>, this can be an NFS path of the Export Storage Domain
|
||||
of the form C<E<lt>hostE<gt>:E<lt>pathE<gt>>, eg:
|
||||
@@ -366,6 +387,11 @@ Print information about the source guest and stop. This option is
|
||||
useful when you are setting up network and bridge maps.
|
||||
See L</NETWORKS AND BRIDGES>.
|
||||
|
||||
=item B<--qemu-boot>
|
||||
|
||||
When using I<-o qemu> only, this boots the guest immediately after
|
||||
virt-v2v finishes.
|
||||
|
||||
=item B<-q>
|
||||
|
||||
=item B<--quiet>
|
||||
|
||||
Reference in New Issue
Block a user