diff --git a/common/mltools/xpath_helpers.ml b/common/mltools/xpath_helpers.ml index 3afee8b21..d2bfd3fb9 100644 --- a/common/mltools/xpath_helpers.ml +++ b/common/mltools/xpath_helpers.ml @@ -40,3 +40,12 @@ let xpath_eval parsefn xpathctx expr = let xpath_string = xpath_eval identity let xpath_int = xpath_eval int_of_string let xpath_int64 = xpath_eval Int64.of_string + +let xpath_get_nodes xpathctx expr = + let obj = Xml.xpath_eval_expression xpathctx expr in + let nodes = ref [] in + for i = 0 to Xml.xpathobj_nr_nodes obj - 1 do + let node = Xml.xpathobj_node obj i in + push_front node nodes + done; + List.rev !nodes diff --git a/common/mltools/xpath_helpers.mli b/common/mltools/xpath_helpers.mli index 3a8190b05..3a2607aeb 100644 --- a/common/mltools/xpath_helpers.mli +++ b/common/mltools/xpath_helpers.mli @@ -25,3 +25,7 @@ val xpath_int : Xml.xpathctx -> string -> int option val xpath_int64 : Xml.xpathctx -> string -> int64 option (** Parse an xpath expression and return a string/int. Returns [Some v], or [None] if the expression doesn't match. *) + +val xpath_get_nodes : Xml.xpathctx -> string -> Xml.node list +(** Parse an XPath expression and return a list with the matching + XML nodes. *) diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml index 02b4d54ff..729f8b67a 100644 --- a/v2v/output_libvirt.ml +++ b/v2v/output_libvirt.ml @@ -55,15 +55,8 @@ let target_features_of_capabilities_doc doc arch = Xml.xpathctx_set_current_context xpathctx node; (* Get guest/features/* nodes. *) - let obj = Xml.xpath_eval_expression xpathctx "features/*" in - - let features = ref [] in - for i = 0 to Xml.xpathobj_nr_nodes obj - 1 do - let feature_node = Xml.xpathobj_node obj i in - let feature_name = Xml.node_name feature_node in - push_front feature_name features - done; - !features + let features = xpath_get_nodes xpathctx "features/*" in + List.map Xml.node_name features ) class output_libvirt oc output_pool = object diff --git a/v2v/test-harness/v2v_test_harness.ml b/v2v/test-harness/v2v_test_harness.ml index ae0033dde..79e97a4b2 100644 --- a/v2v/test-harness/v2v_test_harness.ml +++ b/v2v/test-harness/v2v_test_harness.ml @@ -25,6 +25,7 @@ open Printf open Std_utils open Tools_utils +open Xpath_helpers type test_plan = { guest_clock : float option; @@ -90,29 +91,18 @@ let run ~test ?input_disk ?input_xml ?(test_plan = default_plan) () = g, root in - let nodes_of_xpathobj doc xpathobj = - let nodes = ref [] in - for i = 0 to Xml.xpathobj_nr_nodes xpathobj - 1 do - push_front (Xml.xpathobj_node xpathobj i) nodes - done; - List.rev !nodes - in - let test_boot boot_disk boot_xml_doc = (* Modify boot XML (in memory). *) let xpathctx = Xml.xpath_new_context boot_xml_doc in (* Change to something unique. *) let domname = "tmpv2v-" ^ test in - let xpath = Xml.xpath_eval_expression xpathctx "/domain/name" in - let nodes = nodes_of_xpathobj boot_xml_doc xpath in + let nodes = xpath_get_nodes xpathctx "/domain/name" in List.iter (fun node -> Xml.node_set_content node domname) nodes; (* Limit the RAM used by the guest to 2GB. *) - let xpath = Xml.xpath_eval_expression xpathctx "/domain/memory" in - let nodes = nodes_of_xpathobj boot_xml_doc xpath in - let xpath = Xml.xpath_eval_expression xpathctx "/domain/currentMemory" in - let nodes = nodes @ nodes_of_xpathobj boot_xml_doc xpath in + let nodes = xpath_get_nodes xpathctx "/domain/memory" in + let nodes = nodes @ xpath_get_nodes xpathctx "/domain/currentMemory" in List.iter ( fun node -> let i = int_of_string (Xml.node_as_string node) in @@ -127,8 +117,7 @@ let run ~test ?input_disk ?input_xml ?(test_plan = default_plan) () = let adjustment = t -. time () in assert (adjustment <= 0.); let adjustment = int_of_float adjustment in - let xpath = Xml.xpath_eval_expression xpathctx "/domain/clock" in - let nodes = nodes_of_xpathobj boot_xml_doc xpath in + let nodes = xpath_get_nodes xpathctx "/domain/clock" in let clock_node = match nodes with | [] -> @@ -147,8 +136,7 @@ let run ~test ?input_disk ?input_xml ?(test_plan = default_plan) () = ); (* Remove all devices except for a whitelist. *) - let xpath = Xml.xpath_eval_expression xpathctx "/domain/devices/*" in - let nodes = nodes_of_xpathobj boot_xml_doc xpath in + let nodes = xpath_get_nodes xpathctx "/domain/devices/*" in List.iter ( fun node -> match Xml.node_name node with @@ -157,33 +145,26 @@ let run ~test ?input_disk ?input_xml ?(test_plan = default_plan) () = ) nodes; (* Remove CDROMs. *) - let xpath = - Xml.xpath_eval_expression xpathctx - "/domain/devices/disk[@device=\"cdrom\"]" in - let nodes = nodes_of_xpathobj boot_xml_doc xpath in + let nodes = xpath_get_nodes xpathctx + "/domain/devices/disk[@device=\"cdrom\"]" in List.iter Xml.unlink_node nodes; (* Change settings to destroy ... *) - let xpath = Xml.xpath_eval_expression xpathctx "/domain/on_poweroff" in - let nodes = nodes_of_xpathobj boot_xml_doc xpath in - let xpath = Xml.xpath_eval_expression xpathctx "/domain/on_crash" in - let nodes = nodes @ nodes_of_xpathobj boot_xml_doc xpath in + let nodes = xpath_get_nodes xpathctx "/domain/on_poweroff" in + let nodes = nodes @ xpath_get_nodes xpathctx "/domain/on_crash" in List.iter (fun node -> Xml.node_set_content node "destroy") nodes; (* ... except for which is permitted (for SELinux * relabelling) *) - let xpath = Xml.xpath_eval_expression xpathctx "/domain/on_reboot" in - let nodes = nodes_of_xpathobj boot_xml_doc xpath in + let nodes = xpath_get_nodes xpathctx "/domain/on_reboot" in List.iter (fun node -> Xml.node_set_content node "restart") nodes; (* Get the name of the disk device (eg. "sda"), which is used * for getting disk stats. *) - let xpath = - Xml.xpath_eval_expression xpathctx - "/domain/devices/disk[@device=\"disk\"]/target/@dev" in let dev = - match nodes_of_xpathobj boot_xml_doc xpath with + match xpath_get_nodes xpathctx + "/domain/devices/disk[@device=\"disk\"]/target/@dev" with | [node] -> Xml.node_as_string node | _ -> assert false in @@ -523,10 +504,8 @@ let run ~test ?input_disk ?input_xml ?(test_plan = default_plan) () = (* We need to remember to change the XML to point to the boot overlay. *) let () = let xpathctx = Xml.xpath_new_context boot_xml_doc in - let xpath = - Xml.xpath_eval_expression xpathctx - "/domain/devices/disk[@device=\"disk\"]/source" in - match nodes_of_xpathobj boot_xml_doc xpath with + match xpath_get_nodes xpathctx + "/domain/devices/disk[@device=\"disk\"]/source" with | [node] -> (* Libvirt requires that the path is absolute. *) let abs_boot_disk = Sys.getcwd () // boot_disk in