XXX
No documentation.
Only handles one disk.
Network cards?
What firmware types does kubevirt support.
---
v2v/Makefile.am | 2 +
v2v/cmdline.ml | 20 +++++++++
v2v/output_kubevirt.ml | 115 ++++++++++++++++++++++++++++++++++++++++++++++++
v2v/output_kubevirt.mli | 24 ++++++++++
v2v/utils.ml | 4 ++
v2v/utils.mli | 3 ++
6 files changed, 168 insertions(+)
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
index 8ec002fd3..3fbd3ef82 100644
--- a/v2v/Makefile.am
+++ b/v2v/Makefile.am
@@ -57,6 +57,7 @@ SOURCES_MLI = \
modules_list.mli \
name_from_disk.mli \
output_glance.mli \
+ output_kubevirt.mli \
output_libvirt.mli \
output_local.mli \
output_null.mli \
@@ -115,6 +116,7 @@ SOURCES_ML = \
output_qemu.ml \
output_rhv.ml \
output_vdsm.ml \
+ output_kubevirt.ml \
inspect_source.ml \
target_bus_assignment.ml \
cmdline.ml \
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
index eae97db83..dbe766bf1 100644
--- a/v2v/cmdline.ml
+++ b/v2v/cmdline.ml
@@ -140,6 +140,7 @@ let parse_cmdline () =
error (f_"%s option used more than once on the command line")
"-o";
match mode with
| "glance" -> output_mode := `Glance
+ | "kubevirt" -> output_mode := `Kubevirt
| "libvirt" -> output_mode := `Libvirt
| "disk" | "local" -> output_mode := `Local
| "null" -> output_mode := `Null
@@ -487,6 +488,25 @@ read the man page virt-v2v(1).
Output_glance.output_glance (),
output_format, output_alloc
+ | `Kubevirt ->
+ if output_conn <> None then
+ error_option_cannot_be_used_in_output_mode "kubevirt" "-oc";
+ if output_password <> None then
+ error_option_cannot_be_used_in_output_mode "kubevirt" "-op";
+ let os =
+ match output_storage with
+ | None ->
+ error (f_"-o kubevirt: output directory was not specified, use '-os
/dir'")
+ | Some d when not (is_directory d) ->
+ error (f_"-os %s: output directory does not exist or is not a
directory") d
+ | Some d -> d in
+ if qemu_boot then
+ error_option_cannot_be_used_in_output_mode "kubevirt"
"--qemu-boot";
+ if not do_copy then
+ error_option_cannot_be_used_in_output_mode "kubevirt"
"--no-copy";
+ Output_kubevirt.output_kubevirt os,
+ output_format, output_alloc
+
| `Not_set
| `Libvirt ->
if output_password <> None then
diff --git a/v2v/output_kubevirt.ml b/v2v/output_kubevirt.ml
new file mode 100644
index 000000000..68935a048
--- /dev/null
+++ b/v2v/output_kubevirt.ml
@@ -0,0 +1,115 @@
+(* virt-v2v
+ * Copyright (C) 2018 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 Std_utils
+open Tools_utils
+open Unix_utils
+open Common_gettext.Gettext
+
+open Types
+open Utils
+
+class output_kubevirt dir = object
+ inherit output
+
+ method as_options =
+ sprintf "-o kubevirt -os %s" dir
+
+ method supported_firmware = [ TargetBIOS; TargetUEFI ] (* XXX GUESS *)
+
+ val mutable name = ""
+
+ method prepare_targets source targets =
+ (* Only one disk is supported at present. XXX *)
+ if List.length targets <> 1 then
+ error (f_"-o kubevirt: this output mode only supports a single disk");
+
+ (* Don't use the source name directly, it must be munged
+ * for DNS (RFC 1123).
+ *)
+ name <- PCRE.replace ~global:true (PCRE.compile "[_.]+") "-"
+ source.s_name;
+
+ List.mapi (
+ fun i t ->
+ (* This is the PVC name which is generated by the
+ * script that calls virt-v2v.
+ *)
+ let target_file =
+ TargetFile (dir // sprintf "%s-disk-%d" name (i+1)) in
+ { t with target_file }
+ ) targets
+
+ method create_metadata source targets target_buses
+ guestcaps inspect target_firmware =
+ (* Create the YAML-format metadata. *)
+ with_open_out (dir // name ^ ".yaml") (
+ fun chan ->
+ let fpf fs = fprintf chan fs in
+ fpf "apiVersion: kubevirt.io/v1alpha1\n";
+ fpf "kind: OfflineVirtualMachine\n";
+ fpf "metadata:\n";
+ fpf " name: %s\n" (yaml_quote name);
+ fpf "domain:\n";
+ fpf " cpu:\n";
+ fpf " cores: %d\n" source.s_vcpu;
+ fpf " resources:\n";
+ fpf " requests:\n";
+ fpf " memory: %Ld%s\n" (source.s_memory /^ 1024_L)
"KiB";
+ fpf " os:\n";
+ fpf " osinfo: %s\n" (yaml_quote inspect.i_osinfo);
+ fpf " devices:\n";
+ fpf " disks:\n";
+
+ (* virt-v2v (and indeed hardware) doesn't really work this way,
+ * in that there are several buses which may have multiple disks,
+ * and we're throwing all that careful mapping away, but here we
+ * are ... XXX
+ *)
+ let disk_bus =
+ match guestcaps.gcaps_block_bus with
+ | Virtio_blk -> "virtio"
+ | Virtio_SCSI -> "scsi"
+ | IDE -> "ide" in
+
+ List.iteri (
+ fun i t ->
+ fpf " - name: disk-%d\n" (i+1);
+ fpf " disk:\n";
+ fpf " bus: %s\n" disk_bus;
+ fpf " volumeName: volume-%d\n" (i+1)
+ ) targets;
+
+ fpf " volumes:\n";
+ List.iteri (
+ fun i t ->
+ let filename =
+ match t.target_file with
+ | TargetFile t -> Filename.basename t
+ | TargetURI _ -> assert false in
+ fpf " - name: volume-%d\n" (i+1);
+ fpf " persistentVolumeClaim:\n";
+ fpf " name: %s\n" (yaml_quote filename)
+ ) targets
+ )
+end
+
+let output_kubevirt = new output_kubevirt
+let () = Modules_list.register_output_module "kubevirt"
diff --git a/v2v/output_kubevirt.mli b/v2v/output_kubevirt.mli
new file mode 100644
index 000000000..3ff0041c7
--- /dev/null
+++ b/v2v/output_kubevirt.mli
@@ -0,0 +1,24 @@
+(* virt-v2v
+ * Copyright (C) 2018 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 kubevirt] target. *)
+
+val output_kubevirt : string -> Types.output
+(** [output_kubevirt dir] creates and returns a new
+ {!Types.output} object specialized for writing output to
+ KubeVirt. *)
diff --git a/v2v/utils.ml b/v2v/utils.ml
index 58331207f..e23aee378 100644
--- a/v2v/utils.ml
+++ b/v2v/utils.ml
@@ -39,6 +39,10 @@ let uri_quote str =
done;
String.concat "" (List.rev !xs)
+(* YAML quoting of strings. *)
+let yaml_quote str =
+ "'" ^ String.replace str "'" "''" ^
"'"
+
(* Map guest architecture found by inspection to the architecture
* that KVM must emulate. Note for x86 we assume a 64 bit hypervisor.
*)
diff --git a/v2v/utils.mli b/v2v/utils.mli
index 4a444aaa0..c5afaf88f 100644
--- a/v2v/utils.mli
+++ b/v2v/utils.mli
@@ -21,6 +21,9 @@
val uri_quote : string -> string
(** Take a string and perform %xx escaping as used in some parts of URLs. *)
+val yaml_quote : string -> string
+(** Returns a fully quoted YAML string (including end quotes). *)
+
val kvm_arch : string -> string
(** Map guest architecture found by inspection to the architecture
that KVM must emulate. Note for x86 we assume a 64 bit hypervisor. *)
--
2.13.2