|
|
ffd6ed |
From 200c392c36db4800e915e3c4de16ea6294dd4cd7 Mon Sep 17 00:00:00 2001
|
|
|
ffd6ed |
From: "Richard W.M. Jones" <rjones@redhat.com>
|
|
|
ffd6ed |
Date: Fri, 28 Aug 2015 13:53:24 +0100
|
|
|
ffd6ed |
Subject: [PATCH] v2v: Convert xpath_to_* to use xpath convenience functions.
|
|
|
ffd6ed |
|
|
|
ffd6ed |
In -i libvirtxml, -i ova and -o libvirt drivers, replace the ad hoc
|
|
|
ffd6ed |
xpath_to_* functions with use of the new xpath convenience functions
|
|
|
ffd6ed |
introduced in the previous commit.
|
|
|
ffd6ed |
|
|
|
ffd6ed |
This is not entirely refactoring because I fixed a few bugs found by
|
|
|
ffd6ed |
type safety.
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(cherry picked from commit 261d05749fb75e60d56d3c2d92589de9dca7ca09)
|
|
|
ffd6ed |
---
|
|
|
ffd6ed |
v2v/input_libvirtxml.ml | 281 ++++++++++++++++++++++--------------------------
|
|
|
ffd6ed |
v2v/input_ova.ml | 85 +++++++--------
|
|
|
ffd6ed |
v2v/output_libvirt.ml | 23 ++--
|
|
|
ffd6ed |
3 files changed, 180 insertions(+), 209 deletions(-)
|
|
|
ffd6ed |
|
|
|
ffd6ed |
diff --git a/v2v/input_libvirtxml.ml b/v2v/input_libvirtxml.ml
|
|
|
ffd6ed |
index 16c34a6..be48a75 100644
|
|
|
ffd6ed |
--- a/v2v/input_libvirtxml.ml
|
|
|
ffd6ed |
+++ b/v2v/input_libvirtxml.ml
|
|
|
ffd6ed |
@@ -39,37 +39,23 @@ let parse_libvirt_xml ?conn ~verbose xml =
|
|
|
ffd6ed |
|
|
|
ffd6ed |
let doc = Xml.parse_memory xml in
|
|
|
ffd6ed |
let xpathctx = Xml.xpath_new_context doc in
|
|
|
ffd6ed |
+ let xpath_string = xpath_string xpathctx
|
|
|
ffd6ed |
+ and xpath_int = xpath_int xpathctx
|
|
|
ffd6ed |
+ and xpath_int_default = xpath_int_default xpathctx in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
- let xpath_to_string expr default =
|
|
|
ffd6ed |
- let obj = Xml.xpath_eval_expression xpathctx expr in
|
|
|
ffd6ed |
- if Xml.xpathobj_nr_nodes obj < 1 then default
|
|
|
ffd6ed |
- else (
|
|
|
ffd6ed |
- let node = Xml.xpathobj_node obj 0 in
|
|
|
ffd6ed |
- Xml.node_as_string node
|
|
|
ffd6ed |
- )
|
|
|
ffd6ed |
- and xpath_to_int expr default =
|
|
|
ffd6ed |
- let obj = Xml.xpath_eval_expression xpathctx expr in
|
|
|
ffd6ed |
- if Xml.xpathobj_nr_nodes obj < 1 then default
|
|
|
ffd6ed |
- else (
|
|
|
ffd6ed |
- let node = Xml.xpathobj_node obj 0 in
|
|
|
ffd6ed |
- let str = Xml.node_as_string node in
|
|
|
ffd6ed |
- try int_of_string str
|
|
|
ffd6ed |
- with Failure "int_of_string" ->
|
|
|
ffd6ed |
- error (f_"expecting XML expression to return an integer (expression: %s)")
|
|
|
ffd6ed |
- expr
|
|
|
ffd6ed |
- )
|
|
|
ffd6ed |
- in
|
|
|
ffd6ed |
-
|
|
|
ffd6ed |
- let dom_type = xpath_to_string "/domain/@type" "" in
|
|
|
ffd6ed |
- let name = xpath_to_string "/domain/name/text()" "" in
|
|
|
ffd6ed |
- let memory = xpath_to_int "/domain/memory/text()" (1024 * 1024) in
|
|
|
ffd6ed |
+ let dom_type =
|
|
|
ffd6ed |
+ match xpath_string "/domain/@type" with
|
|
|
ffd6ed |
+ | None | Some "" ->
|
|
|
ffd6ed |
+ error ~prog (f_"in the libvirt XML metadata, <domain type='...'> is missing or empty")
|
|
|
ffd6ed |
+ | Some s -> s in
|
|
|
ffd6ed |
+ let name =
|
|
|
ffd6ed |
+ match xpath_string "/domain/name/text()" with
|
|
|
ffd6ed |
+ | None | Some "" ->
|
|
|
ffd6ed |
+ error ~prog (f_"in the libvirt XML metadata, <name> is missing or empty")
|
|
|
ffd6ed |
+ | Some s -> s in
|
|
|
ffd6ed |
+ let memory = xpath_int_default "/domain/memory/text()" (1024 * 1024) in
|
|
|
ffd6ed |
let memory = Int64.of_int memory *^ 1024L in
|
|
|
ffd6ed |
- let vcpu = xpath_to_int "/domain/vcpu/text()" 1 in
|
|
|
ffd6ed |
-
|
|
|
ffd6ed |
- if dom_type = "" then
|
|
|
ffd6ed |
- error (f_"in the libvirt XML metadata, <domain type='...'> is missing or empty");
|
|
|
ffd6ed |
- if name = "" then
|
|
|
ffd6ed |
- error (f_"in the libvirt XML metadata, <name> is missing or empty");
|
|
|
ffd6ed |
+ let vcpu = xpath_int_default "/domain/vcpu/text()" 1 in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
let features =
|
|
|
ffd6ed |
let features = ref [] in
|
|
|
ffd6ed |
@@ -89,54 +75,53 @@ let parse_libvirt_xml ?conn ~verbose xml =
|
|
|
ffd6ed |
(* Ignore everything except the first <graphics> device. *)
|
|
|
ffd6ed |
let node = Xml.xpathobj_node obj 0 in
|
|
|
ffd6ed |
Xml.xpathctx_set_current_context xpathctx node;
|
|
|
ffd6ed |
- let keymap =
|
|
|
ffd6ed |
- match xpath_to_string "@keymap" "" with "" -> None | k -> Some k in
|
|
|
ffd6ed |
- let password =
|
|
|
ffd6ed |
- match xpath_to_string "@passwd" "" with "" -> None | pw -> Some pw in
|
|
|
ffd6ed |
+ let keymap = xpath_string "@keymap" in
|
|
|
ffd6ed |
+ let password = xpath_string "@passwd" in
|
|
|
ffd6ed |
let listen =
|
|
|
ffd6ed |
let obj = Xml.xpath_eval_expression xpathctx "listen" in
|
|
|
ffd6ed |
let nr_nodes = Xml.xpathobj_nr_nodes obj in
|
|
|
ffd6ed |
if nr_nodes < 1 then (
|
|
|
ffd6ed |
- match xpath_to_string "@listen" "" with "" -> LNone | a -> LAddress a
|
|
|
ffd6ed |
+ match xpath_string "@listen" with
|
|
|
ffd6ed |
+ | None -> LNone | Some a -> LAddress a
|
|
|
ffd6ed |
) else (
|
|
|
ffd6ed |
(* Use only the first <listen> configuration. *)
|
|
|
ffd6ed |
- match xpath_to_string "listen[1]/@type" "" with
|
|
|
ffd6ed |
- | "" -> LNone
|
|
|
ffd6ed |
- | "address" ->
|
|
|
ffd6ed |
- (match xpath_to_string "listen[1]/@address" "" with
|
|
|
ffd6ed |
- | "" -> LNone
|
|
|
ffd6ed |
- | a -> LAddress a
|
|
|
ffd6ed |
+ match xpath_string "listen[1]/@type" with
|
|
|
ffd6ed |
+ | None -> LNone
|
|
|
ffd6ed |
+ | Some "address" ->
|
|
|
ffd6ed |
+ (match xpath_string "listen[1]/@address" with
|
|
|
ffd6ed |
+ | None -> LNone
|
|
|
ffd6ed |
+ | Some a -> LAddress a
|
|
|
ffd6ed |
)
|
|
|
ffd6ed |
- | "network" ->
|
|
|
ffd6ed |
- (match xpath_to_string "listen[1]/@network" "" with
|
|
|
ffd6ed |
- | "" -> LNone
|
|
|
ffd6ed |
- | n -> LNetwork n
|
|
|
ffd6ed |
+ | Some "network" ->
|
|
|
ffd6ed |
+ (match xpath_string "listen[1]/@network" with
|
|
|
ffd6ed |
+ | None -> LNone
|
|
|
ffd6ed |
+ | Some n -> LNetwork n
|
|
|
ffd6ed |
)
|
|
|
ffd6ed |
- | t ->
|
|
|
ffd6ed |
+ | Some t ->
|
|
|
ffd6ed |
warning ~prog (f_"<listen type='%s'> in the input libvirt XML was ignored") t;
|
|
|
ffd6ed |
LNone
|
|
|
ffd6ed |
) in
|
|
|
ffd6ed |
let port =
|
|
|
ffd6ed |
- match xpath_to_string "@autoport" "yes" with
|
|
|
ffd6ed |
- | "no" ->
|
|
|
ffd6ed |
- let port = xpath_to_int "@port" (-1) in
|
|
|
ffd6ed |
- if port >= 0 then Some port
|
|
|
ffd6ed |
- else None
|
|
|
ffd6ed |
+ match xpath_string "@autoport" with
|
|
|
ffd6ed |
+ | Some "no" ->
|
|
|
ffd6ed |
+ (match xpath_int "@port" with
|
|
|
ffd6ed |
+ | Some port when port > 0 -> Some port
|
|
|
ffd6ed |
+ | Some _ | None -> None)
|
|
|
ffd6ed |
| _ -> None in
|
|
|
ffd6ed |
- match xpath_to_string "@type" "" with
|
|
|
ffd6ed |
- | "" -> None
|
|
|
ffd6ed |
- | "vnc" ->
|
|
|
ffd6ed |
+ match xpath_string "@type" with
|
|
|
ffd6ed |
+ | None -> None
|
|
|
ffd6ed |
+ | Some "vnc" ->
|
|
|
ffd6ed |
Some { s_display_type = VNC;
|
|
|
ffd6ed |
s_keymap = keymap; s_password = password; s_listen = listen;
|
|
|
ffd6ed |
s_port = port }
|
|
|
ffd6ed |
- | "spice" ->
|
|
|
ffd6ed |
+ | Some "spice" ->
|
|
|
ffd6ed |
Some { s_display_type = Spice;
|
|
|
ffd6ed |
s_keymap = keymap; s_password = password; s_listen = listen;
|
|
|
ffd6ed |
s_port = port }
|
|
|
ffd6ed |
- | "sdl"|"desktop" as t ->
|
|
|
ffd6ed |
+ | Some ("sdl"|"desktop" as t) ->
|
|
|
ffd6ed |
warning ~prog (f_"virt-v2v does not support local displays, so <graphics type='%s'> in the input libvirt XML was ignored") t;
|
|
|
ffd6ed |
None
|
|
|
ffd6ed |
- | t ->
|
|
|
ffd6ed |
+ | Some t ->
|
|
|
ffd6ed |
warning ~prog (f_"display <graphics type='%s'> in the input libvirt XML was ignored") t;
|
|
|
ffd6ed |
None
|
|
|
ffd6ed |
) in
|
|
|
ffd6ed |
@@ -151,16 +136,16 @@ let parse_libvirt_xml ?conn ~verbose xml =
|
|
|
ffd6ed |
let node = Xml.xpathobj_node obj 0 in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
Xml.xpathctx_set_current_context xpathctx node;
|
|
|
ffd6ed |
- match xpath_to_string "@model" "" with
|
|
|
ffd6ed |
- | "" -> None
|
|
|
ffd6ed |
- | "ac97" -> Some { s_sound_model = AC97 }
|
|
|
ffd6ed |
- | "es1370" -> Some { s_sound_model = ES1370 }
|
|
|
ffd6ed |
- | "ich6" -> Some { s_sound_model = ICH6 }
|
|
|
ffd6ed |
- | "ich9" -> Some { s_sound_model = ICH9 }
|
|
|
ffd6ed |
- | "pcspk" -> Some { s_sound_model = PCSpeaker }
|
|
|
ffd6ed |
- | "sb16" -> Some { s_sound_model = SB16 }
|
|
|
ffd6ed |
- | "usb" -> Some { s_sound_model = USBAudio }
|
|
|
ffd6ed |
- | model ->
|
|
|
ffd6ed |
+ match xpath_string "@model" with
|
|
|
ffd6ed |
+ | None -> None
|
|
|
ffd6ed |
+ | Some "ac97" -> Some { s_sound_model = AC97 }
|
|
|
ffd6ed |
+ | Some "es1370" -> Some { s_sound_model = ES1370 }
|
|
|
ffd6ed |
+ | Some "ich6" -> Some { s_sound_model = ICH6 }
|
|
|
ffd6ed |
+ | Some "ich9" -> Some { s_sound_model = ICH9 }
|
|
|
ffd6ed |
+ | Some "pcspk" -> Some { s_sound_model = PCSpeaker }
|
|
|
ffd6ed |
+ | Some "sb16" -> Some { s_sound_model = SB16 }
|
|
|
ffd6ed |
+ | Some "usb" -> Some { s_sound_model = USBAudio }
|
|
|
ffd6ed |
+ | Some model ->
|
|
|
ffd6ed |
warning ~prog (f_"unknown sound model %s ignored") model;
|
|
|
ffd6ed |
None
|
|
|
ffd6ed |
) in
|
|
|
ffd6ed |
@@ -191,84 +176,80 @@ let parse_libvirt_xml ?conn ~verbose xml =
|
|
|
ffd6ed |
Xml.xpathctx_set_current_context xpathctx node;
|
|
|
ffd6ed |
|
|
|
ffd6ed |
let controller =
|
|
|
ffd6ed |
- let target_bus = xpath_to_string "target/@bus" "" in
|
|
|
ffd6ed |
+ let target_bus = xpath_string "target/@bus" in
|
|
|
ffd6ed |
match target_bus with
|
|
|
ffd6ed |
- | "" -> None
|
|
|
ffd6ed |
- | "ide" -> Some Source_IDE
|
|
|
ffd6ed |
- | "scsi" -> Some Source_SCSI
|
|
|
ffd6ed |
- | "virtio" -> Some Source_virtio_blk
|
|
|
ffd6ed |
- | _ -> None in
|
|
|
ffd6ed |
+ | None -> None
|
|
|
ffd6ed |
+ | Some "ide" -> Some Source_IDE
|
|
|
ffd6ed |
+ | Some "scsi" -> Some Source_SCSI
|
|
|
ffd6ed |
+ | Some "virtio" -> Some Source_virtio_blk
|
|
|
ffd6ed |
+ | Some _ -> None in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
let format =
|
|
|
ffd6ed |
- match xpath_to_string "driver/@type" "" with
|
|
|
ffd6ed |
- | "aio" -> Some "raw" (* Xen wierdness *)
|
|
|
ffd6ed |
- | "" -> None
|
|
|
ffd6ed |
- | format -> Some format in
|
|
|
ffd6ed |
+ match xpath_string "driver/@type" with
|
|
|
ffd6ed |
+ | Some "aio" -> Some "raw" (* Xen wierdness *)
|
|
|
ffd6ed |
+ | None -> None
|
|
|
ffd6ed |
+ | Some format -> Some format in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(* The <disk type='...'> attribute may be 'block', 'file',
|
|
|
ffd6ed |
* 'network' or 'volume'. We ignore any other types.
|
|
|
ffd6ed |
*)
|
|
|
ffd6ed |
- match xpath_to_string "@type" "" with
|
|
|
ffd6ed |
- | "block" ->
|
|
|
ffd6ed |
- let path = xpath_to_string "source/@dev" "" in
|
|
|
ffd6ed |
- if path <> "" then
|
|
|
ffd6ed |
- add_disk path format controller (P_source_dev path)
|
|
|
ffd6ed |
- | "file" ->
|
|
|
ffd6ed |
- let path = xpath_to_string "source/@file" "" in
|
|
|
ffd6ed |
- if path <> "" then
|
|
|
ffd6ed |
- add_disk path format controller (P_source_file path)
|
|
|
ffd6ed |
- | "network" ->
|
|
|
ffd6ed |
+ match xpath_string "@type" with
|
|
|
ffd6ed |
+ | None ->
|
|
|
ffd6ed |
+ warning ~prog (f_"<disk> element with no type attribute ignored")
|
|
|
ffd6ed |
+ | Some "block" ->
|
|
|
ffd6ed |
+ (match xpath_string "source/@dev" with
|
|
|
ffd6ed |
+ | Some path ->
|
|
|
ffd6ed |
+ add_disk path format controller (P_source_dev path)
|
|
|
ffd6ed |
+ | None -> ()
|
|
|
ffd6ed |
+ );
|
|
|
ffd6ed |
+ | Some "file" ->
|
|
|
ffd6ed |
+ (match xpath_string "source/@file" with
|
|
|
ffd6ed |
+ | Some path ->
|
|
|
ffd6ed |
+ add_disk path format controller (P_source_file path)
|
|
|
ffd6ed |
+ | None -> ()
|
|
|
ffd6ed |
+ );
|
|
|
ffd6ed |
+ | Some "network" ->
|
|
|
ffd6ed |
(* We only handle <source protocol="nbd"> here, and that is
|
|
|
ffd6ed |
* intended only for virt-p2v. Any other network disk is
|
|
|
ffd6ed |
* currently ignored.
|
|
|
ffd6ed |
*)
|
|
|
ffd6ed |
- (match xpath_to_string "source/@protocol" "" with
|
|
|
ffd6ed |
- | "nbd" ->
|
|
|
ffd6ed |
- let host = xpath_to_string "source/host/@name" "" in
|
|
|
ffd6ed |
- let port = xpath_to_int "source/host/@port" 0 in
|
|
|
ffd6ed |
- if host <> "" && port > 0 then (
|
|
|
ffd6ed |
- (* Generate a qemu nbd URL.
|
|
|
ffd6ed |
- * XXX Quoting, although it's not needed for virt-p2v.
|
|
|
ffd6ed |
- *)
|
|
|
ffd6ed |
- let path = sprintf "nbd:%s:%d" host port in
|
|
|
ffd6ed |
- add_disk path format controller P_dont_rewrite
|
|
|
ffd6ed |
- )
|
|
|
ffd6ed |
- | "" -> ()
|
|
|
ffd6ed |
- | protocol ->
|
|
|
ffd6ed |
- warning ~prog (f_"network <disk> with <source protocol='%s'> was ignored")
|
|
|
ffd6ed |
+ (match (xpath_string "source/@protocol",
|
|
|
ffd6ed |
+ xpath_string "source/host/@name",
|
|
|
ffd6ed |
+ xpath_int "source/host/@port") with
|
|
|
ffd6ed |
+ | None, _, _ ->
|
|
|
ffd6ed |
+ warning ~prog (f_"<disk type=network> was ignored")
|
|
|
ffd6ed |
+ | Some "nbd", Some ("localhost" as host), Some port when port > 0 ->
|
|
|
ffd6ed |
+ (* virt-p2v: Generate a qemu nbd URL. *)
|
|
|
ffd6ed |
+ let path = sprintf "nbd:%s:%d" host port in
|
|
|
ffd6ed |
+ add_disk path format controller P_dont_rewrite
|
|
|
ffd6ed |
+ | Some protocol, _, _ ->
|
|
|
ffd6ed |
+ warning ~prog (f_"<disk type='network'> with <source protocol='%s'> was ignored")
|
|
|
ffd6ed |
protocol
|
|
|
ffd6ed |
)
|
|
|
ffd6ed |
- | "volume" ->
|
|
|
ffd6ed |
- let pool = xpath_to_string "source/@pool" "" in
|
|
|
ffd6ed |
- let vol = xpath_to_string "source/@volume" "" in
|
|
|
ffd6ed |
- if pool <> "" && vol <> "" then (
|
|
|
ffd6ed |
+ | Some "volume" ->
|
|
|
ffd6ed |
+ (match xpath_string "source/@pool", xpath_string "source/@volume" with
|
|
|
ffd6ed |
+ | None, None | Some _, None | None, Some _ -> ()
|
|
|
ffd6ed |
+ | Some pool, Some vol ->
|
|
|
ffd6ed |
let xml = Domainxml.vol_dumpxml ?conn pool vol in
|
|
|
ffd6ed |
let doc = Xml.parse_memory xml in
|
|
|
ffd6ed |
let xpathctx = Xml.xpath_new_context doc in
|
|
|
ffd6ed |
-
|
|
|
ffd6ed |
- let xpath_to_string expr default =
|
|
|
ffd6ed |
- let obj = Xml.xpath_eval_expression xpathctx expr in
|
|
|
ffd6ed |
- if Xml.xpathobj_nr_nodes obj < 1 then default
|
|
|
ffd6ed |
- else (
|
|
|
ffd6ed |
- let node = Xml.xpathobj_node obj 0 in
|
|
|
ffd6ed |
- Xml.node_as_string node
|
|
|
ffd6ed |
- ) in
|
|
|
ffd6ed |
+ let xpath_string = Utils.xpath_string xpathctx in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(* Use the format specified in the volume itself. *)
|
|
|
ffd6ed |
- let format =
|
|
|
ffd6ed |
- match xpath_to_string "/volume/target/format/@type" "" with
|
|
|
ffd6ed |
- | "" -> None
|
|
|
ffd6ed |
- | format -> Some format in
|
|
|
ffd6ed |
+ let format = xpath_string "/volume/target/format/@type" in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
- match xpath_to_string "/volume/@type" "" with
|
|
|
ffd6ed |
- | "" | "file" ->
|
|
|
ffd6ed |
- let path = xpath_to_string "/volume/target/path/text()" "" in
|
|
|
ffd6ed |
- if path <> "" then
|
|
|
ffd6ed |
- add_disk path format controller (P_source_file path)
|
|
|
ffd6ed |
- | vol_type ->
|
|
|
ffd6ed |
+ (match xpath_string "/volume/@type" with
|
|
|
ffd6ed |
+ | None | Some "file" ->
|
|
|
ffd6ed |
+ (match xpath_string "/volume/target/path/text()" with
|
|
|
ffd6ed |
+ | Some path ->
|
|
|
ffd6ed |
+ add_disk path format controller (P_source_file path)
|
|
|
ffd6ed |
+ | None -> ()
|
|
|
ffd6ed |
+ );
|
|
|
ffd6ed |
+ | Some vol_type ->
|
|
|
ffd6ed |
warning ~prog (f_"<disk type='volume'> with <volume type='%s'> was ignored") vol_type
|
|
|
ffd6ed |
+ )
|
|
|
ffd6ed |
)
|
|
|
ffd6ed |
- | disk_type ->
|
|
|
ffd6ed |
+ | Some disk_type ->
|
|
|
ffd6ed |
warning ~prog (f_"<disk type='%s'> was ignored") disk_type
|
|
|
ffd6ed |
done;
|
|
|
ffd6ed |
get_disks () in
|
|
|
ffd6ed |
@@ -285,18 +266,18 @@ let parse_libvirt_xml ?conn ~verbose xml =
|
|
|
ffd6ed |
Xml.xpathctx_set_current_context xpathctx node;
|
|
|
ffd6ed |
|
|
|
ffd6ed |
let controller =
|
|
|
ffd6ed |
- let target_bus = xpath_to_string "target/@bus" "" in
|
|
|
ffd6ed |
+ let target_bus = xpath_string "target/@bus" in
|
|
|
ffd6ed |
match target_bus with
|
|
|
ffd6ed |
- | "" -> None
|
|
|
ffd6ed |
- | "ide" -> Some Source_IDE
|
|
|
ffd6ed |
- | "scsi" -> Some Source_SCSI
|
|
|
ffd6ed |
- | "virtio" -> Some Source_virtio_blk
|
|
|
ffd6ed |
- | _ -> None in
|
|
|
ffd6ed |
+ | None -> None
|
|
|
ffd6ed |
+ | Some "ide" -> Some Source_IDE
|
|
|
ffd6ed |
+ | Some "scsi" -> Some Source_SCSI
|
|
|
ffd6ed |
+ | Some "virtio" -> Some Source_virtio_blk
|
|
|
ffd6ed |
+ | Some _ -> None in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
let typ =
|
|
|
ffd6ed |
- match xpath_to_string "@device" "" with
|
|
|
ffd6ed |
- | "cdrom" -> CDROM
|
|
|
ffd6ed |
- | "floppy" -> Floppy
|
|
|
ffd6ed |
+ match xpath_string "@device" with
|
|
|
ffd6ed |
+ | Some "cdrom" -> CDROM
|
|
|
ffd6ed |
+ | Some "floppy" -> Floppy
|
|
|
ffd6ed |
| _ -> assert false (* libxml2 error? *) in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
let disk =
|
|
|
ffd6ed |
@@ -314,31 +295,31 @@ let parse_libvirt_xml ?conn ~verbose xml =
|
|
|
ffd6ed |
let node = Xml.xpathobj_node obj i in
|
|
|
ffd6ed |
Xml.xpathctx_set_current_context xpathctx node;
|
|
|
ffd6ed |
|
|
|
ffd6ed |
- let mac = xpath_to_string "mac/@address" "" in
|
|
|
ffd6ed |
+ let mac = xpath_string "mac/@address" in
|
|
|
ffd6ed |
let mac =
|
|
|
ffd6ed |
match mac with
|
|
|
ffd6ed |
- | ""
|
|
|
ffd6ed |
- | "00:00:00:00:00:00" (* thanks, VMware *) -> None
|
|
|
ffd6ed |
- | mac -> Some mac in
|
|
|
ffd6ed |
+ | None
|
|
|
ffd6ed |
+ | Some "00:00:00:00:00:00" (* thanks, VMware *) -> None
|
|
|
ffd6ed |
+ | Some mac -> Some mac in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
let vnet_type =
|
|
|
ffd6ed |
- match xpath_to_string "@type" "" with
|
|
|
ffd6ed |
- | "network" -> Some Network
|
|
|
ffd6ed |
- | "bridge" -> Some Bridge
|
|
|
ffd6ed |
- | _ -> None in
|
|
|
ffd6ed |
+ match xpath_string "@type" with
|
|
|
ffd6ed |
+ | Some "network" -> Some Network
|
|
|
ffd6ed |
+ | Some "bridge" -> Some Bridge
|
|
|
ffd6ed |
+ | None | Some _ -> None in
|
|
|
ffd6ed |
match vnet_type with
|
|
|
ffd6ed |
| None -> ()
|
|
|
ffd6ed |
| Some vnet_type ->
|
|
|
ffd6ed |
- let vnet = xpath_to_string "source/@network | source/@bridge" "" in
|
|
|
ffd6ed |
- if vnet <> "" then (
|
|
|
ffd6ed |
- let nic = {
|
|
|
ffd6ed |
- s_mac = mac;
|
|
|
ffd6ed |
- s_vnet = vnet;
|
|
|
ffd6ed |
- s_vnet_orig = vnet;
|
|
|
ffd6ed |
- s_vnet_type = vnet_type
|
|
|
ffd6ed |
- } in
|
|
|
ffd6ed |
- nics := nic :: !nics
|
|
|
ffd6ed |
- )
|
|
|
ffd6ed |
+ match xpath_string "source/@network | source/@bridge" with
|
|
|
ffd6ed |
+ | None -> ()
|
|
|
ffd6ed |
+ | Some vnet ->
|
|
|
ffd6ed |
+ let nic = {
|
|
|
ffd6ed |
+ s_mac = mac;
|
|
|
ffd6ed |
+ s_vnet = vnet;
|
|
|
ffd6ed |
+ s_vnet_orig = vnet;
|
|
|
ffd6ed |
+ s_vnet_type = vnet_type
|
|
|
ffd6ed |
+ } in
|
|
|
ffd6ed |
+ nics := nic :: !nics
|
|
|
ffd6ed |
done;
|
|
|
ffd6ed |
List.rev !nics in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
diff --git a/v2v/input_ova.ml b/v2v/input_ova.ml
|
|
|
ffd6ed |
index ab8c27b..d1b7021 100644
|
|
|
ffd6ed |
--- a/v2v/input_ova.ml
|
|
|
ffd6ed |
+++ b/v2v/input_ova.ml
|
|
|
ffd6ed |
@@ -180,41 +180,27 @@ object
|
|
|
ffd6ed |
Xml.xpath_register_ns xpathctx
|
|
|
ffd6ed |
"vssd" "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData";
|
|
|
ffd6ed |
|
|
|
ffd6ed |
- let xpath_to_string expr default =
|
|
|
ffd6ed |
- let obj = Xml.xpath_eval_expression xpathctx expr in
|
|
|
ffd6ed |
- if Xml.xpathobj_nr_nodes obj < 1 then default
|
|
|
ffd6ed |
- else (
|
|
|
ffd6ed |
- let node = Xml.xpathobj_node obj 0 in
|
|
|
ffd6ed |
- Xml.node_as_string node
|
|
|
ffd6ed |
- )
|
|
|
ffd6ed |
- and xpath_to_int expr default =
|
|
|
ffd6ed |
- let obj = Xml.xpath_eval_expression xpathctx expr in
|
|
|
ffd6ed |
- if Xml.xpathobj_nr_nodes obj < 1 then default
|
|
|
ffd6ed |
- else (
|
|
|
ffd6ed |
- let node = Xml.xpathobj_node obj 0 in
|
|
|
ffd6ed |
- let str = Xml.node_as_string node in
|
|
|
ffd6ed |
- try int_of_string str
|
|
|
ffd6ed |
- with Failure "int_of_string" ->
|
|
|
ffd6ed |
- error (f_"expecting XML expression to return an integer (expression: %s)")
|
|
|
ffd6ed |
- expr
|
|
|
ffd6ed |
- )
|
|
|
ffd6ed |
- in
|
|
|
ffd6ed |
+ let xpath_string = xpath_string xpathctx
|
|
|
ffd6ed |
+ and xpath_int = xpath_int xpathctx
|
|
|
ffd6ed |
+ and xpath_string_default = xpath_string_default xpathctx
|
|
|
ffd6ed |
+ and xpath_int_default = xpath_int_default xpathctx in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(* Search for vm name. *)
|
|
|
ffd6ed |
let name =
|
|
|
ffd6ed |
- xpath_to_string "/ovf:Envelope/ovf:VirtualSystem/ovf:Name/text()" "" in
|
|
|
ffd6ed |
- if name = "" then
|
|
|
ffd6ed |
- error (f_"could not parse ovf:Name from OVF document");
|
|
|
ffd6ed |
+ match xpath_string "/ovf:Envelope/ovf:VirtualSystem/ovf:Name/text()" with
|
|
|
ffd6ed |
+ | None | Some "" ->
|
|
|
ffd6ed |
+ error (f_"could not parse ovf:Name from OVF document")
|
|
|
ffd6ed |
+ | Some name -> name in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(* Search for memory. *)
|
|
|
ffd6ed |
- let memory = xpath_to_int "/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:ResourceType/text()=4]/rasd:VirtualQuantity/text()" (1024 * 1024) in
|
|
|
ffd6ed |
+ let memory = xpath_int_default "/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:ResourceType/text()=4]/rasd:VirtualQuantity/text()" (1024 * 1024) in
|
|
|
ffd6ed |
let memory = Int64.of_int (memory * 1024 * 1024) in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(* Search for number of vCPUs. *)
|
|
|
ffd6ed |
- let vcpu = xpath_to_int "/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:ResourceType/text()=3]/rasd:VirtualQuantity/text()" 1 in
|
|
|
ffd6ed |
+ let vcpu = xpath_int_default "/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:ResourceType/text()=3]/rasd:VirtualQuantity/text()" 1 in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(* BIOS or EFI firmware? *)
|
|
|
ffd6ed |
- let firmware = xpath_to_string "/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/vmw:Config[@vmw:key=\"firmware\"]/@vmw:value" "bios" in
|
|
|
ffd6ed |
+ let firmware = xpath_string_default "/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/vmw:Config[@vmw:key=\"firmware\"]/@vmw:value" "bios" in
|
|
|
ffd6ed |
let firmware =
|
|
|
ffd6ed |
match firmware with
|
|
|
ffd6ed |
| "bios" -> BIOS
|
|
|
ffd6ed |
@@ -225,16 +211,16 @@ object
|
|
|
ffd6ed |
(* Helper function to return the parent controller of a disk. *)
|
|
|
ffd6ed |
let parent_controller id =
|
|
|
ffd6ed |
let expr = sprintf "/ovf:Envelope/ovf:VirtualSystem/ovf:VirtualHardwareSection/ovf:Item[rasd:InstanceID/text()=%d]/rasd:ResourceType/text()" id in
|
|
|
ffd6ed |
- let controller = xpath_to_int expr 0 in
|
|
|
ffd6ed |
+ let controller = xpath_int expr in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(* 6: iscsi controller, 5: ide *)
|
|
|
ffd6ed |
match controller with
|
|
|
ffd6ed |
- | 6 -> Some Source_SCSI
|
|
|
ffd6ed |
- | 5 -> Some Source_IDE
|
|
|
ffd6ed |
- | 0 ->
|
|
|
ffd6ed |
+ | Some 6 -> Some Source_SCSI
|
|
|
ffd6ed |
+ | Some 5 -> Some Source_IDE
|
|
|
ffd6ed |
+ | None ->
|
|
|
ffd6ed |
warning ~prog (f_"ova disk has no parent controller, please report this as a bug supplying the *.ovf file extracted from the ova");
|
|
|
ffd6ed |
None
|
|
|
ffd6ed |
- | _ ->
|
|
|
ffd6ed |
+ | Some controller ->
|
|
|
ffd6ed |
warning ~prog (f_"ova disk has an unknown VMware controller type (%d), please report this as a bug supplying the *.ovf file extracted from the ova")
|
|
|
ffd6ed |
controller;
|
|
|
ffd6ed |
None
|
|
|
ffd6ed |
@@ -251,27 +237,32 @@ object
|
|
|
ffd6ed |
Xml.xpathctx_set_current_context xpathctx n;
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(* XXX We assume the OVF lists these in order.
|
|
|
ffd6ed |
- let address = xpath_to_int "rasd:AddressOnParent/text()" 0 in
|
|
|
ffd6ed |
+ let address = xpath_int "rasd:AddressOnParent/text()" in
|
|
|
ffd6ed |
*)
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(* Find the parent controller. *)
|
|
|
ffd6ed |
- let parent_id = xpath_to_int "rasd:Parent/text()" 0 in
|
|
|
ffd6ed |
+ let parent_id = xpath_int "rasd:Parent/text()" in
|
|
|
ffd6ed |
let controller =
|
|
|
ffd6ed |
match parent_id with
|
|
|
ffd6ed |
- | 0 -> None
|
|
|
ffd6ed |
- | id -> parent_controller id in
|
|
|
ffd6ed |
+ | None -> None
|
|
|
ffd6ed |
+ | Some id -> parent_controller id in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
Xml.xpathctx_set_current_context xpathctx n;
|
|
|
ffd6ed |
- let file_id = xpath_to_string "rasd:HostResource/text()" "" in
|
|
|
ffd6ed |
+ let file_id = xpath_string_default "rasd:HostResource/text()" "" in
|
|
|
ffd6ed |
let rex = Str.regexp "^ovf:/disk/\\(.*\\)" in
|
|
|
ffd6ed |
if Str.string_match rex file_id 0 then (
|
|
|
ffd6ed |
(* Chase the references through to the actual file name. *)
|
|
|
ffd6ed |
let file_id = Str.matched_group 1 file_id in
|
|
|
ffd6ed |
let expr = sprintf "/ovf:Envelope/ovf:DiskSection/ovf:Disk[@ovf:diskId='%s']/@ovf:fileRef" file_id in
|
|
|
ffd6ed |
- let file_ref = xpath_to_string expr "" in
|
|
|
ffd6ed |
- if file_ref == "" then error (f_"error parsing disk fileRef");
|
|
|
ffd6ed |
+ let file_ref =
|
|
|
ffd6ed |
+ match xpath_string expr with
|
|
|
ffd6ed |
+ | None -> error (f_"error parsing disk fileRef")
|
|
|
ffd6ed |
+ | Some s -> s in
|
|
|
ffd6ed |
let expr = sprintf "/ovf:Envelope/ovf:References/ovf:File[@ovf:id='%s']/@ovf:href" file_ref in
|
|
|
ffd6ed |
- let filename = xpath_to_string expr "" in
|
|
|
ffd6ed |
+ let filename =
|
|
|
ffd6ed |
+ match xpath_string expr with
|
|
|
ffd6ed |
+ | None -> error (f_"no href in ovf:File (id=%s)") file_ref
|
|
|
ffd6ed |
+ | Some s -> s in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(* Does the file exist and is it readable? *)
|
|
|
ffd6ed |
let filename = exploded // filename in
|
|
|
ffd6ed |
@@ -318,19 +309,22 @@ object
|
|
|
ffd6ed |
for i = 0 to nr_nodes-1 do
|
|
|
ffd6ed |
let n = Xml.xpathobj_node obj i in
|
|
|
ffd6ed |
Xml.xpathctx_set_current_context xpathctx n;
|
|
|
ffd6ed |
- let id = xpath_to_int "rasd:ResourceType/text()" 0 in
|
|
|
ffd6ed |
- assert (id = 14 || id = 15 || id = 16);
|
|
|
ffd6ed |
+ let id =
|
|
|
ffd6ed |
+ match xpath_int "rasd:ResourceType/text()" with
|
|
|
ffd6ed |
+ | None -> assert false
|
|
|
ffd6ed |
+ | Some (14|15|16 as i) -> i
|
|
|
ffd6ed |
+ | Some _ -> assert false in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(* XXX We assume the OVF lists these in order.
|
|
|
ffd6ed |
- let address = xpath_to_int "rasd:AddressOnParent/text()" 0 in
|
|
|
ffd6ed |
+ let address = xpath_int "rasd:AddressOnParent/text()" in
|
|
|
ffd6ed |
*)
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(* Find the parent controller. *)
|
|
|
ffd6ed |
- let parent_id = xpath_to_int "rasd:Parent/text()" 0 in
|
|
|
ffd6ed |
+ let parent_id = xpath_int "rasd:Parent/text()" in
|
|
|
ffd6ed |
let controller =
|
|
|
ffd6ed |
match parent_id with
|
|
|
ffd6ed |
- | 0 -> None
|
|
|
ffd6ed |
- | id -> parent_controller id in
|
|
|
ffd6ed |
+ | None -> None
|
|
|
ffd6ed |
+ | Some id -> parent_controller id in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
let typ =
|
|
|
ffd6ed |
match id with
|
|
|
ffd6ed |
@@ -352,7 +346,8 @@ object
|
|
|
ffd6ed |
for i = 0 to nr_nodes-1 do
|
|
|
ffd6ed |
let n = Xml.xpathobj_node obj i in
|
|
|
ffd6ed |
Xml.xpathctx_set_current_context xpathctx n;
|
|
|
ffd6ed |
- let vnet = xpath_to_string "rasd:ElementName/text()" (sprintf"eth%d" i) in
|
|
|
ffd6ed |
+ let vnet =
|
|
|
ffd6ed |
+ xpath_string_default "rasd:ElementName/text()" (sprintf"eth%d" i) in
|
|
|
ffd6ed |
let nic = {
|
|
|
ffd6ed |
s_mac = None;
|
|
|
ffd6ed |
s_vnet = vnet;
|
|
|
ffd6ed |
diff --git a/v2v/output_libvirt.ml b/v2v/output_libvirt.ml
|
|
|
ffd6ed |
index de4aeb4..16510d2 100644
|
|
|
ffd6ed |
--- a/v2v/output_libvirt.ml
|
|
|
ffd6ed |
+++ b/v2v/output_libvirt.ml
|
|
|
ffd6ed |
@@ -350,23 +350,18 @@ class output_libvirt verbose oc output_pool = object
|
|
|
ffd6ed |
let xml = Domainxml.pool_dumpxml ?conn:oc output_pool in
|
|
|
ffd6ed |
let doc = Xml.parse_memory xml in
|
|
|
ffd6ed |
let xpathctx = Xml.xpath_new_context doc in
|
|
|
ffd6ed |
-
|
|
|
ffd6ed |
- let xpath_to_string expr default =
|
|
|
ffd6ed |
- let obj = Xml.xpath_eval_expression xpathctx expr in
|
|
|
ffd6ed |
- if Xml.xpathobj_nr_nodes obj < 1 then default
|
|
|
ffd6ed |
- else (
|
|
|
ffd6ed |
- let node = Xml.xpathobj_node obj 0 in
|
|
|
ffd6ed |
- Xml.node_as_string node
|
|
|
ffd6ed |
- )
|
|
|
ffd6ed |
- in
|
|
|
ffd6ed |
+ let xpath_string = xpath_string xpathctx in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(* We can only output to a pool of type 'dir' (directory). *)
|
|
|
ffd6ed |
- let pool_type = xpath_to_string "/pool/@type" "" in
|
|
|
ffd6ed |
- if pool_type <> "dir" then
|
|
|
ffd6ed |
+ if xpath_string "/pool/@type" <> Some "dir" then
|
|
|
ffd6ed |
error (f_"-o libvirt: output pool '%s' is not a directory (type='dir'). See virt-v2v(1) section \"OUTPUT TO LIBVIRT\"") output_pool;
|
|
|
ffd6ed |
- let target_path = xpath_to_string "/pool/target/path/text()" "" in
|
|
|
ffd6ed |
- if target_path = "" || not (is_directory target_path) then
|
|
|
ffd6ed |
- error (f_"-o libvirt: output pool '%s' has type='dir' but the /pool/target/path element either does not exist or is not a local directory. See virt-v2v(1) section \"OUTPUT TO LIBVIRT\"") output_pool;
|
|
|
ffd6ed |
+ let target_path =
|
|
|
ffd6ed |
+ match xpath_string "/pool/target/path/text()" with
|
|
|
ffd6ed |
+ | None ->
|
|
|
ffd6ed |
+ error (f_"-o libvirt: output pool '%s' does not have /pool/target/path element. See virt-v2v(1) section \"OUTPUT TO LIBVIRT\"") output_pool
|
|
|
ffd6ed |
+ | Some dir when not (is_directory dir) ->
|
|
|
ffd6ed |
+ error (f_"-o libvirt: output pool '%s' has type='dir' but the /pool/target/path element is not a local directory. See virt-v2v(1) section \"OUTPUT TO LIBVIRT\"") output_pool
|
|
|
ffd6ed |
+ | Some dir -> dir in
|
|
|
ffd6ed |
|
|
|
ffd6ed |
(* Set up the targets. *)
|
|
|
ffd6ed |
List.map (
|
|
|
ffd6ed |
--
|
|
|
ffd6ed |
1.8.3.1
|
|
|
ffd6ed |
|