[Libguestfs] [PATCH 2/3] v2v: ovf: Create OVF more aligned with the standard

Tomáš Golembiovský tgolembi at redhat.com
Sun Feb 18 14:26:09 UTC 2018


For historical reasons the OVF used in RHV export domain contains some
deviations from the OVF standard. The format used in -o rhv has to
remain fixed but for -o vdsm and we could produce much nicer OVF. This
patch serves as a preparatory step to this.

The main reason for creating different OVF is that it can be used to
create VM by oVirt REST API. The RHV export domain flavor cannot be used
that way.

For now the virt-v2v behavior is unchanged. The modified output will be
enabled in some later patch.

Signed-off-by: Tomáš Golembiovský <tgolembi at redhat.com>
---
 v2v/create_ovf.ml  | 108 ++++++++++++++++++++++++++++++++++++++---------------
 v2v/create_ovf.mli |   2 +-
 v2v/output_rhv.ml  |   2 +-
 v2v/output_vdsm.ml |   3 +-
 4 files changed, 82 insertions(+), 33 deletions(-)

diff --git a/v2v/create_ovf.ml b/v2v/create_ovf.ml
index f60ca9ed3..8d16cf175 100644
--- a/v2v/create_ovf.ml
+++ b/v2v/create_ovf.ml
@@ -269,7 +269,7 @@ let create_meta_files output_alloc sd_uuid image_uuids targets =
 
 (* Create the OVF file. *)
 let rec create_ovf source targets guestcaps inspect
-    output_alloc sd_uuid image_uuids vol_uuids vm_uuid =
+    output_alloc sd_uuid image_uuids vol_uuids vm_uuid rhv_export_flavor =
   assert (List.length targets = List.length vol_uuids);
 
   let memsize_mb = source.s_memory /^ 1024L /^ 1024L in
@@ -288,12 +288,22 @@ let rec create_ovf source targets guestcaps inspect
     ] [
       Comment generated_by;
       e "References" [] [];
-      e "Section" ["xsi:type", "ovf:NetworkSection_Type"] [
-        e "Info" [] [PCData "List of networks"]
-      ];
-      e "Section" ["xsi:type", "ovf:DiskSection_Type"] [
-        e "Info" [] [PCData "List of Virtual Disks"]
-      ];
+      if rhv_export_flavor then
+        e "Section" ["xsi:type", "ovf:NetworkSection_Type"] [
+          e "Info" [] [PCData "List of networks"]
+        ]
+      else
+        e "NetworkSection" [] [
+          e "Info" [] [PCData "List of networks"]
+        ];
+      if rhv_export_flavor then
+        e "Section" ["xsi:type", "ovf:DiskSection_Type"] [
+          e "Info" [] [PCData "List of Virtual Disks"]
+        ]
+      else
+        e "DiskSection" [] [
+          e "Info" [] [PCData "List of Virtual Disks"]
+        ];
 
       let content_subnodes = ref [
         e "Name" [] [PCData source.s_name];
@@ -326,11 +336,18 @@ let rec create_ovf source targets guestcaps inspect
       );
 
       List.push_back content_subnodes (
-        e "Section" ["ovf:id", vm_uuid; "ovf:required", "false";
-                     "xsi:type", "ovf:OperatingSystemSection_Type"] [
+        let osinfo_subnodes = [
           e "Info" [] [PCData inspect.i_product_name];
           e "Description" [] [PCData ostype];
-          ]
+        ] in
+        if rhv_export_flavor then
+          e "Section" ["ovf:id", vm_uuid; "ovf:required", "false";
+                      "xsi:type", "ovf:OperatingSystemSection_Type"]
+            osinfo_subnodes
+        else
+          e "OperatingSystemSection" ["ovf:id", vm_uuid;
+                                      "ovf:required", "false"]
+            osinfo_subnodes
       );
 
       let virtual_hardware_section_items = ref [
@@ -424,16 +441,23 @@ let rec create_ovf source targets guestcaps inspect
         );
 
       List.push_back content_subnodes (
-        e "Section" ["xsi:type", "ovf:VirtualHardwareSection_Type"]
-          !virtual_hardware_section_items
+        if rhv_export_flavor then
+          e "Section" ["xsi:type", "ovf:VirtualHardwareSection_Type"]
+            !virtual_hardware_section_items
+        else
+          e "VirtualHardwareSection" [] !virtual_hardware_section_items
       );
 
-      e "Content" ["ovf:id", "out"; "xsi:type", "ovf:VirtualSystem_Type"]
-        !content_subnodes
+      if rhv_export_flavor then
+        e "Content" ["ovf:id", "out"; "xsi:type", "ovf:VirtualSystem_Type"]
+          !content_subnodes
+      else
+        e "VirtualSystem" ["ovf:id", "out"] !content_subnodes
     ] in
 
   (* Add disks to the OVF XML. *)
-  add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf;
+  add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids
+    rhv_export_flavor ovf;
 
   (* Old virt-v2v ignored removable media. XXX *)
 
@@ -462,20 +486,30 @@ let rec create_ovf source targets guestcaps inspect
   ovf
 
 (* This modifies the OVF DOM, adding a section for each disk. *)
-and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf =
+and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids
+    rhv_export_flavor ovf =
   let references =
     let nodes = path_to_nodes ovf ["ovf:Envelope"; "References"] in
     match nodes with
     | [] | _::_::_ -> assert false
     | [node] -> node in
   let disk_section =
-    let sections = path_to_nodes ovf ["ovf:Envelope"; "Section"] in
-    try find_node_by_attr sections ("xsi:type", "ovf:DiskSection_Type")
-    with Not_found -> assert false in
+    let nodes = path_to_nodes ovf ["ovf:Envelope"; "DiskSection"] in
+    match nodes with
+    | [node] -> node
+    | [] | _::_::_ -> let sections =
+         path_to_nodes ovf ["ovf:Envelope"; "Section"] in
+       try find_node_by_attr sections ("xsi:type", "ovf:DiskSection_Type")
+       with Not_found -> assert false in
   let virtualhardware_section =
-    let sections = path_to_nodes ovf ["ovf:Envelope"; "Content"; "Section"] in
-    try find_node_by_attr sections ("xsi:type", "ovf:VirtualHardwareSection_Type")
-    with Not_found -> assert false in
+    let nodes = path_to_nodes ovf
+      ["ovf:Envelope"; "VirtualSystem"; "VirtualHardwareSection"] in
+    match nodes with
+    | [node] -> node
+    | [] | _::_::_ -> let sections =
+         path_to_nodes ovf ["ovf:Envelope"; "Content"; "Section"] in
+       try find_node_by_attr sections ("xsi:type", "ovf:VirtualHardwareSection_Type")
+       with Not_found -> assert false in
 
   (* Iterate over the disks, adding them to the OVF document. *)
   List.iteri (
@@ -489,7 +523,12 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf =
       let is_bootable_drive = i == 0 in
       let boot_order = i+1 in
 
-      let fileref = sprintf "%s/%s" image_uuid vol_uuid in
+      let fileref =
+        if rhv_export_flavor then
+          sprintf "%s/%s" image_uuid vol_uuid
+        else
+          vol_uuid
+        in
 
       (* ovf:size and ovf:actual_size fields are integer GBs.  If you
        * use floating point numbers then RHV will fail to parse them.
@@ -535,7 +574,7 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf =
       (* Add disk to DiskSection. *)
       let disk =
         let attrs = ref [
-          "ovf:diskId", vol_uuid;
+          "ovf:diskId", if rhv_export_flavor then vol_uuid else image_uuid ;
           "ovf:size", Int64.to_string size_gb;
           "ovf:fileRef", fileref;
           "ovf:parentRef", "";
@@ -595,13 +634,22 @@ and add_disks targets guestcaps output_alloc sd_uuid image_uuids vol_uuids ovf =
 (* This modifies the OVF DOM, adding a section for each NIC. *)
 and add_networks nics guestcaps ovf =
   let network_section =
-    let sections = path_to_nodes ovf ["ovf:Envelope"; "Section"] in
-    try find_node_by_attr sections ("xsi:type", "ovf:NetworkSection_Type")
-    with Not_found -> assert false in
+    let nodes = path_to_nodes ovf ["ovf:Envelope"; "NetworkSection"] in
+    match nodes with
+    | [node] -> node
+    | [] | _::_::_ -> let sections =
+         path_to_nodes ovf ["ovf:Envelope"; "Section"] in
+       try find_node_by_attr sections ("xsi:type", "ovf:NetworkSection_Type")
+       with Not_found -> assert false in
   let virtualhardware_section =
-    let sections = path_to_nodes ovf ["ovf:Envelope"; "Content"; "Section"] in
-    try find_node_by_attr sections ("xsi:type", "ovf:VirtualHardwareSection_Type")
-    with Not_found -> assert false in
+    let nodes = path_to_nodes ovf
+      ["ovf:Envelope"; "VirtualSystem"; "VirtualHardwareSection"] in
+    match nodes with
+    | [node] -> node
+    | [] | _::_::_ -> let sections =
+         path_to_nodes ovf ["ovf:Envelope"; "Content"; "Section"] in
+       try find_node_by_attr sections ("xsi:type", "ovf:VirtualHardwareSection_Type")
+       with Not_found -> assert false in
 
   (* Iterate over the NICs, adding them to the OVF document. *)
   List.iteri (
diff --git a/v2v/create_ovf.mli b/v2v/create_ovf.mli
index 07e8af6a0..43a8cfc71 100644
--- a/v2v/create_ovf.mli
+++ b/v2v/create_ovf.mli
@@ -25,7 +25,7 @@
     create OVF for another target management system then we would need
     to heavily modify or even duplicate this code. *)
 
-val create_ovf : Types.source -> Types.target list -> Types.guestcaps -> Types.inspect -> Types.output_allocation -> string -> string list -> string list -> string -> DOM.doc
+val create_ovf : Types.source -> Types.target list -> Types.guestcaps -> Types.inspect -> Types.output_allocation -> string -> string list -> string list -> string ->  bool -> DOM.doc
 (** Create the OVF file.
 
     Actually a {!DOM} document is created, not a file.  It can be written
diff --git a/v2v/output_rhv.ml b/v2v/output_rhv.ml
index 0b732e4cf..77e7a627e 100644
--- a/v2v/output_rhv.ml
+++ b/v2v/output_rhv.ml
@@ -275,7 +275,7 @@ object
 
     (* Create the metadata. *)
     let ovf = Create_ovf.create_ovf source targets guestcaps inspect
-      output_alloc esd_uuid image_uuids vol_uuids vm_uuid in
+      output_alloc esd_uuid image_uuids vol_uuids vm_uuid true in
 
     (* Write it to the metadata file. *)
     let dir = esd_mp // esd_uuid // "master" // "vms" // vm_uuid in
diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml
index 828ad7bda..b2188dd8b 100644
--- a/v2v/output_vdsm.ml
+++ b/v2v/output_vdsm.ml
@@ -175,7 +175,8 @@ object
       output_alloc dd_uuid
       vdsm_params.image_uuids
       vdsm_params.vol_uuids
-      vdsm_params.vm_uuid in
+      vdsm_params.vm_uuid
+      true in
 
     (* Write it to the metadata file. *)
     let file = vdsm_params.ovf_output // vdsm_params.vm_uuid ^ ".ovf" in
-- 
2.16.1




More information about the Libguestfs mailing list