[Libguestfs] [PATCH v2] v2v: Add support for libosinfo metadata

Martin Kletzander mkletzan at redhat.com
Fri Nov 23 20:14:55 UTC 2018


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 at redhat.com>
---
v2:
 - Added support for SLED
 - Fixed test-v2v-i-ova test output

 v2v/create_libvirt_xml.ml  | 119 ++++++++++++++++++++++++++++++++++++-
 v2v/create_libvirt_xml.mli |   1 +
 v2v/output_libvirt.ml      |   4 +-
 v2v/output_local.ml        |   4 +-
 v2v/test-v2v-i-ova.xml     |   5 ++
 5 files changed, 128 insertions(+), 5 deletions(-)

diff --git a/v2v/create_libvirt_xml.ml b/v2v/create_libvirt_xml.ml
index 55e83e8bc1b9..6b2fb874a5a6 100644
--- a/v2v/create_libvirt_xml.ml
+++ b/v2v/create_libvirt_xml.ml
@@ -34,8 +34,112 @@ 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;
+      i_product_name = product } when String.find product "Desktop" >= 0 ->
+    Some (sprintf "http://suse.com/sled/%d" major)
+
+  | { i_type = "linux"; i_distro = "sles";
+      i_major_version = major; i_minor_version = minor;
+      i_product_name = product } when String.find product "Desktop" >= 0 ->
+    Some (sprintf "http://suse.com/sled/%d.%d" major minor)
+
+  | { 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 +153,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
diff --git a/v2v/test-v2v-i-ova.xml b/v2v/test-v2v-i-ova.xml
index b277193a87ed..7c19828316c8 100644
--- a/v2v/test-v2v-i-ova.xml
+++ b/v2v/test-v2v-i-ova.xml
@@ -2,6 +2,11 @@
 <domain type='kvm'>
   <!-- generated by -->
   <name>TestOva</name>
+  <metadata>
+    <libosinfo:libosinfo xmlns:libosinfo='http://libosinfo.org/xmlns/libvirt/domain/1.0'>
+      <libosinfo:os id='http://microsoft.com/win/7'/>
+    </libosinfo:libosinfo>
+  </metadata>
   <memory unit='KiB'>2097152</memory>
   <currentMemory unit='KiB'>2097152</currentMemory>
   <vcpu>1</vcpu>
-- 
2.19.2




More information about the Libguestfs mailing list