Martin Kletzander
2018-Nov-23 20:14 UTC
[Libguestfs] [PATCH v2] v2v: Add support for libosinfo metadata
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@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
Richard W.M. Jones
2018-Nov-23 20:58 UTC
Re: [Libguestfs] [PATCH v2] v2v: Add support for libosinfo metadata
I've pushed this. Thanks for the contribution! Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://people.redhat.com/~rjones/virt-top