[Pkg-libvirt-commits] [libguestfs] 140/266: v2v: Add support for remote ESX connections.

Hilko Bengen bengen at moszumanska.debian.org
Fri Oct 3 14:41:53 UTC 2014


This is an automated email from the git hooks/post-receive script.

bengen pushed a commit to annotated tag debian/1%1.27.35-1
in repository libguestfs.

commit ccb47f93ff52a4f80498072cf679e502b782f655
Author: Richard W.M. Jones <rjones at redhat.com>
Date:   Wed Aug 20 21:16:57 2014 +0100

    v2v: Add support for remote ESX connections.
    
    This allows `-ic esx://...' to work because we map the strange source
    URI used by ESX to a remote HTTPS connection.
    
    Example disk section that this handles:
    
        <disk type='file' device='disk'>
          <source file='[datastore1] Windows/Windows.vmdk'/>
          <target dev='sda' bus='scsi'/>
          <address type='drive' controller='0' bus='0' target='0' unit='0'/>
        </disk>
---
 po/POTFILES-ml        |  1 +
 v2v/Makefile.am       |  2 ++
 v2v/lib_esx.ml        | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++
 v2v/lib_esx.mli       | 23 ++++++++++++++++
 v2v/source_libvirt.ml | 38 ++++++++++++++++++++++++++-
 v2v/utils.ml          | 13 +++++++++
 6 files changed, 149 insertions(+), 1 deletion(-)

diff --git a/po/POTFILES-ml b/po/POTFILES-ml
index aeaac76..2a5ce03 100644
--- a/po/POTFILES-ml
+++ b/po/POTFILES-ml
@@ -86,6 +86,7 @@ v2v/DOM.ml
 v2v/cmdline.ml
 v2v/convert_linux.ml
 v2v/convert_windows.ml
+v2v/lib_esx.ml
 v2v/lib_linux.ml
 v2v/source_disk.ml
 v2v/source_libvirt.ml
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
index 0f43951..94801d1 100644
--- a/v2v/Makefile.am
+++ b/v2v/Makefile.am
@@ -28,6 +28,7 @@ SOURCES_MLI = \
 	convert_linux.mli \
 	convert_windows.mli \
 	DOM.mli \
+	lib_esx.mli \
 	lib_linux.mli \
 	source_disk.mli \
 	source_libvirt.mli \
@@ -43,6 +44,7 @@ SOURCES_ML = \
 	utils.ml \
 	xml.ml \
 	DOM.ml \
+	lib_esx.ml \
 	lib_linux.ml \
 	cmdline.ml \
 	source_disk.ml \
diff --git a/v2v/lib_esx.ml b/v2v/lib_esx.ml
new file mode 100644
index 0000000..df5ee4d
--- /dev/null
+++ b/v2v/lib_esx.ml
@@ -0,0 +1,73 @@
+(* virt-v2v
+ * Copyright (C) 2009-2014 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+(** Functions for dealing with ESX. *)
+
+open Xml
+open Utils
+
+open Printf
+
+let esx_re = Str.regexp "^\\[\\(.*\\)\\] \\(.*\\)\\.vmdk$"
+
+(* Map an ESX <source/> to a qemu URI using the cURL driver
+ * in qemu.  The 'path' will be something like
+ *
+ *   "[datastore1] Fedora 20/Fedora 20.vmdk"
+ *
+ * including those literal spaces in the string.
+ *
+ * We want to convert that into the following URL:
+ *   "https://user:password@server/folder/Fedora 20/Fedora 20-flat.vmdk" ^
+ *     "?dcPath=ha-datacenter&dsName=datastore1"
+ *
+ * Note that the URL we create here is passed to qemu-img and is
+ * ultimately parsed by curl_easy_setopt (CURLOPT_URL).
+ *
+ * XXX Old virt-v2v could also handle snapshots, ie:
+ *
+ *   "[datastore1] Fedora 20/Fedora 20-NNNNNN.vmdk"
+ *
+ * However this requires access to the server which we don't necessarily
+ * have here.
+ *)
+let map_path_to_uri uri path =
+  if not (Str.string_match esx_re path 0) then
+    path
+  else (
+    let datastore = Str.matched_group 1 path
+    and vmdk = Str.matched_group 2 path in
+
+    let user =
+      match uri.uri_user with
+      | None -> ""
+      | Some user -> user ^ "@" (* No need to quote it, see RFC 2617. *) in
+    let server =
+      match uri.uri_server with
+      | None -> assert false (* checked by caller *)
+      | Some server -> server in
+    let port =
+      match uri.uri_port with
+      | 443 -> ""
+      | n when n >= 1 -> ":" ^ string_of_int n
+      | _ -> "" in
+
+    sprintf
+      "https://%s%s%s/folder/%s-flat.vmdk?dcPath=ha-datacenter&dsName=%s"
+      user server port vmdk (uri_quote datastore)
+  )
diff --git a/v2v/lib_esx.mli b/v2v/lib_esx.mli
new file mode 100644
index 0000000..9a3f7e5
--- /dev/null
+++ b/v2v/lib_esx.mli
@@ -0,0 +1,23 @@
+(* virt-v2v
+ * Copyright (C) 2009-2014 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+(** Functions for dealing with ESX. *)
+
+val map_path_to_uri : Xml.uri -> string -> string
+(** Map a VMware path like "[datastore1] guest/guest.vmdk" to the
+    URL where we can fetch the data. *)
diff --git a/v2v/source_libvirt.ml b/v2v/source_libvirt.ml
index 2f19426..6ca8120 100644
--- a/v2v/source_libvirt.ml
+++ b/v2v/source_libvirt.ml
@@ -236,6 +236,7 @@ let create_xml ?(map_source_file = identity) ?(map_source_dev = identity) xml =
     s_nics = nics;
   }
 
+(* -i libvirtxml *)
 let create_from_xml file =
   let xml = read_whole_file file in
 
@@ -252,11 +253,46 @@ let create_from_xml file =
 
   create_xml ~map_source_file xml
 
+(* -i libvirt [-ic libvirt_uri] *)
 let create libvirt_uri guest =
+  (* Depending on the libvirt URI we may need to convert <source/>
+   * paths so we can access them remotely (if that is possible).  This
+   * is only true for remote, non-NULL URIs.  (We assume the user
+   * doesn't try setting $LIBVIRT_URI.  If they do that then all bets
+   * are off).
+   *)
+  let map_source_file, map_source_dev =
+    match libvirt_uri with
+    | None -> None, None
+    | Some orig_uri ->
+      let { Xml.uri_server = server; uri_scheme = scheme } as uri =
+        try Xml.parse_uri orig_uri
+        with Invalid_argument msg ->
+          error (f_"could not parse '-ic %s'.  Original error message was: %s")
+            orig_uri msg in
+      match server, scheme with
+      | None, _
+      | Some "", _ ->                   (* Not a remote URI. *)
+        None, None
+      | Some _, None                    (* No scheme? *)
+      | Some _, Some "" ->
+        None, None
+      | Some _, Some "esx" ->           (* esx://... *)
+        let f = Lib_esx.map_path_to_uri uri in Some f, Some f
+      (* XXX Missing: Look for qemu+ssh://, xen+ssh:// and use an ssh
+       * connection.  This was supported in old virt-v2v.
+       *)
+      | Some _, Some _ ->               (* Unknown remote scheme. *)
+        warning ~prog (f_"no support for remote libvirt connections to '-ic %s'.  The conversion may fail when it tries to read the source disks.")
+          orig_uri;
+        None, None in
+
+  (* Get the libvirt XML. *)
   let cmd =
     match libvirt_uri with
     | None -> sprintf "virsh dumpxml %s" (quote guest)
     | Some uri -> sprintf "virsh -c %s dumpxml %s" (quote uri) (quote guest) in
   let lines = external_command ~prog cmd in
   let xml = String.concat "\n" lines in
-  create_xml xml
+
+  create_xml ?map_source_file ?map_source_dev xml
diff --git a/v2v/utils.ml b/v2v/utils.ml
index f065a66..b541b1d 100644
--- a/v2v/utils.ml
+++ b/v2v/utils.ml
@@ -46,6 +46,19 @@ let xml_quote_pcdata str =
   let str = Common_utils.replace_str str ">" ">" in
   str
 
+(* URI quoting. *)
+let uri_quote str =
+  let len = String.length str in
+  let xs = ref [] in
+  for i = 0 to len-1 do
+    xs :=
+      (match str.[i] with
+      | ('a'..'z' | '0'..'9') as c -> String.make 1 c
+      | c -> sprintf "%%%02x" (Char.code c)
+      ) :: !xs
+  done;
+  String.concat "" (List.rev !xs)
+
 external drive_name : int -> string = "v2v_utils_drive_name"
 
 let compare_app2_versions app1 app2 =

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-libvirt/libguestfs.git



More information about the Pkg-libvirt-commits mailing list