There's a standardized libosinfo namespace for libvirt domain metadata. For now
it supports the id of the OS only. However that is still a very helpful feature
that is already supported in gnome-boxes and virt-manager (at least).
The discussion happened here:
https://www.redhat.com/archives/libosinfo/2018-September/msg00003.html
So let's add the support to local and libvirt outputs.
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
v2v/create_libvirt_xml.ml | 109 ++++++++++++++++++++++++++++++++++++-
v2v/create_libvirt_xml.mli | 1 +
v2v/output_libvirt.ml | 4 +-
v2v/output_local.ml | 4 +-
4 files changed, 113 insertions(+), 5 deletions(-)
diff --git a/v2v/create_libvirt_xml.ml b/v2v/create_libvirt_xml.ml
index 55e83e8bc1b9..180f3768792b 100644
--- a/v2v/create_libvirt_xml.ml
+++ b/v2v/create_libvirt_xml.ml
@@ -34,8 +34,102 @@ let find_target_disk targets { s_disk_id = id } =
try List.find (fun t -> t.target_overlay.ov_source.s_disk_id = id) targets
with Not_found -> assert false
+let get_osinfo_id = function
+ | { i_type = "linux"; i_distro = "rhel";
+ i_major_version = major; i_minor_version = minor } ->
+ Some (sprintf "http://redhat.com/rhel/%d.%d" major minor)
+
+ | { i_type = "linux"; i_distro = "centos";
+ i_major_version = major; i_minor_version = minor } when major < 7 ->
+ Some (sprintf "http://centos.org/centos/%d.%d" major minor)
+
+ | { i_type = "linux"; i_distro = "centos"; i_major_version = major
} ->
+ Some (sprintf "http://centos.org/centos/%d.0" major)
+
+ | { i_type = "linux"; i_distro = "sles";
+ i_major_version = major; i_minor_version = 0 } ->
+ Some (sprintf "http://suse.com/sles/%d" major)
+
+ | { i_type = "linux"; i_distro = "sles";
+ i_major_version = major; i_minor_version = minor } ->
+ Some (sprintf "http://suse.com/sles/%d.%d" major minor)
+
+ | { i_type = "linux"; i_distro = "opensuse";
+ i_major_version = major; i_minor_version = minor } ->
+ Some (sprintf "http://opensuse.org/opensuse/%d.%d" major minor)
+
+ | { i_type = "linux"; i_distro = "debian"; i_major_version = major
} ->
+ Some (sprintf "http://debian.org/debian/%d" major)
+
+ | { i_type = "linux"; i_distro = "ubuntu";
+ i_major_version = major; i_minor_version = minor } ->
+ Some (sprintf "http://ubuntu.com/ubuntu/%d.%02d" major minor)
+
+ | { i_type = "linux"; i_distro = "fedora"; i_major_version = major
} ->
+ Some (sprintf "http://fedoraproject.org/fedora/%d" major)
+
+ | { i_type = "windows"; i_major_version = major; i_minor_version = minor }
+ when major < 4 ->
+ Some (sprintf "http://microsoft.com/win/%d.%d" major minor)
+
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 1 } ->
+ Some "http://microsoft.com/win/xp"
+
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2;
+ i_product_name = product } when String.find product "XP" >= 0 ->
+ Some "http://microsoft.com/win/xp"
+
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2;
+ i_product_name = product } when String.find product "R2" >= 0 ->
+ Some "http://microsoft.com/win/2k3r2"
+
+ | { i_type = "windows"; i_major_version = 5; i_minor_version = 2 } ->
+ Some "http://microsoft.com/win/2k3"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 0;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k8"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 0 } ->
+ Some "http://microsoft.com/win/vista"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 1;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k8r2"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 1 } ->
+ Some "http://microsoft.com/win/7"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 2;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k12"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 2 } ->
+ Some "http://microsoft.com/win/8"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 3;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k12r2"
+
+ | { i_type = "windows"; i_major_version = 6; i_minor_version = 3 } ->
+ Some "http://microsoft.com/win/8.1"
+
+ | { i_type = "windows"; i_major_version = 10; i_minor_version = 0;
+ i_product_variant = "Server" } ->
+ Some "http://microsoft.com/win/2k16"
+
+ | { i_type = "windows"; i_major_version = 10; i_minor_version = 0 } ->
+ Some "http://microsoft.com/win/10"
+
+ | { i_type = typ; i_distro = distro;
+ i_major_version = major; i_minor_version = minor; i_arch = arch;
+ i_product_name = product } ->
+ warning (f_"unknown guest operating system: %s %s %d.%d %s (%s)")
+ typ distro major minor arch product;
+ None
+
let create_libvirt_xml ?pool source targets target_buses guestcaps
- target_features target_firmware =
+ target_features target_firmware inspect =
(* The main body of the libvirt XML document. *)
let body = ref [] in
@@ -49,6 +143,19 @@ let create_libvirt_xml ?pool source targets target_buses guestcaps
| Some genid -> List.push_back body (e "genid" [] [PCData genid])
);
+
+ (match get_osinfo_id inspect with
+ | None -> ()
+ | Some osinfo_id ->
+ List.push_back_list body [
+ e "metadata" [] [
+ e "libosinfo:libosinfo" ["xmlns:libosinfo",
"http://libosinfo.org/xmlns/libvirt/domain/1.0"] [
+ e "libosinfo:os" ["id", osinfo_id] [];
+ ];
+ ];
+ ];
+ );
+
let memory_k = source.s_memory /^ 1024L in
List.push_back_list body [
e "memory" ["unit", "KiB"] [PCData (Int64.to_string
memory_k)];
diff --git a/v2v/create_libvirt_xml.mli b/v2v/create_libvirt_xml.mli
index 3f883c625c8a..9a596208481a 100644
--- a/v2v/create_libvirt_xml.mli
+++ b/v2v/create_libvirt_xml.mli
@@ -22,6 +22,7 @@ val create_libvirt_xml : ?pool:string -> Types.source ->
Types.target list ->
Types.target_buses ->
Types.guestcaps -> string list ->
Types.target_firmware ->
+ Types.inspect ->
DOM.doc
(** [create_libvirt_xml ?pool source targets target_buses guestcaps
target_features target_firmware] creates the final libvirt XML
diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml
index 1271bdc2f5e3..9008b05079cd 100644
--- a/v2v/output_libvirt.ml
+++ b/v2v/output_libvirt.ml
@@ -143,7 +143,7 @@ class output_libvirt oc output_pool = object
error_unless_uefi_firmware guestcaps.gcaps_arch
method create_metadata source targets
- target_buses guestcaps _ target_firmware =
+ target_buses guestcaps inspect target_firmware =
(* We copied directly into the final pool directory. However we
* have to tell libvirt.
*)
@@ -172,7 +172,7 @@ class output_libvirt oc output_pool = object
(* Create the metadata. *)
let doc =
create_libvirt_xml ~pool:pool_name source targets target_buses
- guestcaps target_features target_firmware in
+ guestcaps target_features target_firmware inspect in
let tmpfile, chan = Filename.open_temp_file "v2vlibvirt" ".xml"
in
DOM.doc_to_chan chan doc;
diff --git a/v2v/output_local.ml b/v2v/output_local.ml
index 2f4b4e6c9cfd..3a00ed58a72d 100644
--- a/v2v/output_local.ml
+++ b/v2v/output_local.ml
@@ -49,7 +49,7 @@ class output_local dir = object
error_unless_uefi_firmware guestcaps.gcaps_arch
method create_metadata source targets
- target_buses guestcaps _ target_firmware =
+ target_buses guestcaps inspect target_firmware =
(* We don't know what target features the hypervisor supports, but
* assume a common set that libvirt supports.
*)
@@ -61,7 +61,7 @@ class output_local dir = object
let doc =
create_libvirt_xml source targets target_buses
- guestcaps target_features target_firmware in
+ guestcaps target_features target_firmware inspect in
let name = source.s_name in
let file = dir // name ^ ".xml" in
--
2.19.2