[Libguestfs] [PATCH 3/4] v2v: Use libvirt-supplied <vmware:datacenterpath> if available.

Richard W.M. Jones rjones at redhat.com
Fri Oct 9 11:53:24 UTC 2015


In libvirt >= 1.2.20, the VMware libvirt driver supplies the correct
dcPath to use via <vmware:datacenterpath> in the libvirt XML.  If
libvirt passes us this element, use it.

This code still allows the user to override dcPath using the --dcPath
option on the command line, but that's mainly for safety so we can fix
any problems in virt-v2v or libvirt in the field.  As we get more
confident in libvirt and as libvirt 1.2.20 is more widely adopted, we
will be able to deprecate this parameter entirely.

Thanks: Matthias Bolte for adding the <vmware:datacenterpath> element
to libvirt in
https://libvirt.org/git/?p=libvirt.git;a=commit;h=636a99058758a0447482f3baad94de8de3ab1151
---
 v2v/input_libvirt_vcenter_https.ml | 48 +++++++++++++++++++++++++++-----------
 v2v/vCenter.ml                     |  4 +---
 v2v/vCenter.mli                    |  6 ++++-
 v2v/virt-v2v.pod                   |  9 +++----
 4 files changed, 43 insertions(+), 24 deletions(-)

diff --git a/v2v/input_libvirt_vcenter_https.ml b/v2v/input_libvirt_vcenter_https.ml
index 0f1a648..a5b3c8b 100644
--- a/v2v/input_libvirt_vcenter_https.ml
+++ b/v2v/input_libvirt_vcenter_https.ml
@@ -56,19 +56,6 @@ let map_source_to_uri ?readahead dcPath password uri scheme server path =
     let datastore = Str.matched_group 1 path
     and path = Str.matched_group 2 path in
 
-    (* Get the dcPath. *)
-    let dcPath =
-      match dcPath with
-      | None ->
-         let dcPath = VCenter.guess_dcPath uri scheme in
-         if verbose () then
-           printf "vcenter: calculated dcPath as: %s\n" dcPath;
-         dcPath
-      | Some dcPath ->
-         if verbose () then
-           printf "vcenter: using --dcpath from the command line: %s\n" dcPath;
-         dcPath in
-
     let port =
       match uri.uri_port with
       | 443 -> ""
@@ -131,11 +118,12 @@ let map_source_to_uri ?readahead dcPath password uri scheme server path =
 
 (* Subclass specialized for handling VMware vCenter over https. *)
 class input_libvirt_vcenter_https
-  dcPath password libvirt_uri parsed_uri scheme server guest =
+  cmdline_dcPath password libvirt_uri parsed_uri scheme server guest =
 object
   inherit input_libvirt password libvirt_uri guest
 
   val saved_source_paths = Hashtbl.create 13
+  val mutable dcPath = ""
 
   method source () =
     if verbose () then
@@ -150,6 +138,38 @@ object
     let xml = Domainxml.dumpxml ?password ?conn:libvirt_uri guest in
     let source, disks = parse_libvirt_xml ?conn:libvirt_uri xml in
 
+    (* Find the <vmware:datacenterpath> element from the XML, if it
+     * exists.  This was added in libvirt >= 1.2.20.
+     *)
+    let xml_dcPath =
+      let doc = Xml.parse_memory xml in
+      let xpathctx = Xml.xpath_new_context doc in
+      Xml.xpath_register_ns xpathctx
+        "vmware" "http://libvirt.org/schemas/domain/vmware/1.0";
+      let xpath_string = xpath_string xpathctx in
+      xpath_string "/domain/vmware:datacenterpath" in
+
+    (* Calculate the dcPath we're going to use. *)
+    dcPath <- (
+      match cmdline_dcPath, xml_dcPath with
+      (* Command line --dcpath parameter overrides everything, allowing
+       * users to correct any mistakes in v2v or libvirt.
+       *)
+      | Some p, (None|Some _) ->
+         if verbose () then
+           printf "vcenter: using --dcpath from the command line: %s\n" p;
+         p
+      | None, Some p ->
+         if verbose () then
+           printf "vcenter: using <vmware:datacenterpath> from libvirt: %s\n" p;
+         p
+      | None, None ->
+         let p = VCenter.guess_dcPath parsed_uri scheme in
+         if verbose () then
+           printf "vcenter: guessed dcPath from URI: %s\n" p;
+         p
+    );
+
     (* Save the original source paths, so that we can remap them again
      * in [#adjust_overlay_parameters].
      *)
diff --git a/v2v/vCenter.ml b/v2v/vCenter.ml
index 20dd964..9ff9415 100644
--- a/v2v/vCenter.ml
+++ b/v2v/vCenter.ml
@@ -132,9 +132,7 @@ let guess_dcPath uri = function
           * However if there is a cluster involved then the URI may be
           * /Folder/Datacenter/Cluster/esxi but dcPath=Folder/Datacenter/Cluster
           * won't work.  In this case the user has to adjust the path to
-          * remove the Cluster name (which still works in libvirt).  There
-          * should be a way to ask the libvirt vpx driver for the correct
-          * path, but there isn't. XXX  See also RHBZ#1256823.
+          * remove the Cluster name (which still works in libvirt).
           *)
          (* Collapse multiple slashes to single slash. *)
          let path = Str.global_replace multiple_slash "/" path in
diff --git a/v2v/vCenter.mli b/v2v/vCenter.mli
index 10a9657..87583c0 100644
--- a/v2v/vCenter.mli
+++ b/v2v/vCenter.mli
@@ -37,4 +37,8 @@ val get_session_cookie : string option -> string -> Xml.uri -> bool -> string ->
 
 val guess_dcPath : Xml.uri -> string -> string
 (** Try to guess the dcPath parameter from a URI.  The mapping is
-    not precise. *)
+    not precise.
+
+    This function is only used with [libvirt < 1.2.20] because later
+    versions of libvirt provide the dcPath (see
+    https://bugzilla.redhat.com/1263574). *)
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
index 09eb3ea..ae87986 100644
--- a/v2v/virt-v2v.pod
+++ b/v2v/virt-v2v.pod
@@ -252,6 +252,9 @@ See I<--network> below.
 
 =item B<--dcpath> Folder/Datacenter
 
+B<NB:> You don't need to use this parameter if you have
+S<libvirt E<ge> 1.2.20>.
+
 For VMware vCenter, override the C<dcPath=...> parameter used to
 select the datacenter.  Virt-v2v can usually calculate this from the
 C<vpx://> URI, but if it gets it wrong, then you can override it using
@@ -981,12 +984,6 @@ added to the URI, eg:
 
  vpx://user@server/Folder/Datacenter/esxi
 
-Virt-v2v needs to calculate the C<dcPath> parameter from the URI, and
-it does this by removing the final C</esxi> element, so in the above
-example C<dcPath=Folder/Datacenter>.  As it is not always possible to
-correctly calculate C<dcPath> from the URI, you can override this
-using the I<--dcpath> parameter.
-
 For full details of libvirt URIs, see: L<http://libvirt.org/drvesx.html>
 
 Typical errors from libvirt / virsh when the URI is wrong include:
-- 
2.5.0




More information about the Libguestfs mailing list