206 lines
8.2 KiB
Diff
206 lines
8.2 KiB
Diff
|
From 40730615d2f691bc72777b4cb7356e2177edc1e1 Mon Sep 17 00:00:00 2001
|
||
|
From: "Richard W.M. Jones" <rjones@redhat.com>
|
||
|
Date: Mon, 15 Jan 2024 14:48:56 +0000
|
||
|
Subject: [PATCH] virt-v2v: -i vmx: Remove dependency of ssh.ml on Xml.uri
|
||
|
|
||
|
Xml.uri is a convenient way to pass the multiple ssh fields to
|
||
|
virt-v2v and is still used internally by the -i vmx code. However
|
||
|
don't leak this awkward implementation into the new ssh.ml module.
|
||
|
|
||
|
Like Nbdkit_ssh, we'll only deal with the explicit (password, port,
|
||
|
server, user, path) fields separately.
|
||
|
|
||
|
Note after this refactoring:
|
||
|
|
||
|
- The new Ssh module interface looks broadly similar to the
|
||
|
Nbdkit_ssh interface.
|
||
|
|
||
|
- vmx_source_of_arg assertions are no longer required inside the new
|
||
|
Ssh module, which was a mild layering violation before.
|
||
|
|
||
|
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
|
||
|
---
|
||
|
input/input_vmx.ml | 21 ++++++++++++++++-----
|
||
|
input/parse_domain_from_vmx.ml | 22 +++++++++++++++++++---
|
||
|
input/ssh.ml | 32 +++++++++++---------------------
|
||
|
input/ssh.mli | 21 ++++++++++-----------
|
||
|
4 files changed, 56 insertions(+), 40 deletions(-)
|
||
|
|
||
|
diff --git a/input/input_vmx.ml b/input/input_vmx.ml
|
||
|
index b9cce10f..b3426fa2 100644
|
||
|
--- a/input/input_vmx.ml
|
||
|
+++ b/input/input_vmx.ml
|
||
|
@@ -83,22 +83,33 @@ module VMX = struct
|
||
|
let socket = sprintf "%s/in%d" dir i in
|
||
|
On_exit.unlink socket;
|
||
|
|
||
|
- let vmx_path = Ssh.path_of_uri uri in
|
||
|
+ let vmx_path =
|
||
|
+ match uri.uri_path with
|
||
|
+ | None -> assert false (* checked by vmx_source_of_arg *)
|
||
|
+ | Some path -> path in
|
||
|
let abs_path = absolute_path_from_other_file vmx_path filename in
|
||
|
let flat_vmdk = PCRE.replace (PCRE.compile "\\.vmdk$")
|
||
|
"-flat.vmdk" abs_path in
|
||
|
|
||
|
+ let server =
|
||
|
+ match uri.uri_server with
|
||
|
+ | None -> assert false (* checked by vmx_source_of_arg *)
|
||
|
+ | Some server -> server in
|
||
|
+ let port =
|
||
|
+ match uri.uri_port with
|
||
|
+ | i when i <= 0 -> None
|
||
|
+ | i -> Some (string_of_int i) in
|
||
|
+ let user = uri.Xml.uri_user in
|
||
|
+
|
||
|
(* RHBZ#1774386 *)
|
||
|
- if not (Ssh.remote_file_exists uri flat_vmdk) then
|
||
|
+ if not (Ssh.remote_file_exists ~password ?port ~server ?user
|
||
|
+ flat_vmdk) then
|
||
|
error (f_"This transport does not support guests with snapshots. \
|
||
|
Either collapse the snapshots for this guest and try \
|
||
|
the conversion again, or use one of the alternate \
|
||
|
conversion methods described in \
|
||
|
virt-v2v-input-vmware(1) section \"NOTES\".");
|
||
|
|
||
|
- let server = Ssh.server_of_uri uri in
|
||
|
- let port = Option.map string_of_int (Ssh.port_of_uri uri) in
|
||
|
- let user = uri.Xml.uri_user in
|
||
|
let cor = dir // "convert" in
|
||
|
let bandwidth = options.bandwidth in
|
||
|
let nbdkit = Nbdkit_ssh.create_ssh ?bandwidth ~cor ~password
|
||
|
diff --git a/input/parse_domain_from_vmx.ml b/input/parse_domain_from_vmx.ml
|
||
|
index 0719738c..99c86b1a 100644
|
||
|
--- a/input/parse_domain_from_vmx.ml
|
||
|
+++ b/input/parse_domain_from_vmx.ml
|
||
|
@@ -334,9 +334,22 @@ let parse_domain_from_vmx vmx_source =
|
||
|
let vmx =
|
||
|
match vmx_source with
|
||
|
| File filename -> Parse_vmx.parse_file filename
|
||
|
- | SSH (_, uri) ->
|
||
|
+ | SSH (password, uri) ->
|
||
|
+ let server =
|
||
|
+ match uri.uri_server with
|
||
|
+ | None -> assert false (* checked by vmx_source_of_arg *)
|
||
|
+ | Some server -> server in
|
||
|
+ let port =
|
||
|
+ match uri.uri_port with
|
||
|
+ | i when i <= 0 -> None
|
||
|
+ | i -> Some (string_of_int i) in
|
||
|
+ let user = uri.Xml.uri_user in
|
||
|
+ let path =
|
||
|
+ match uri.uri_path with
|
||
|
+ | None -> assert false (* checked by vmx_source_of_arg *)
|
||
|
+ | Some path -> path in
|
||
|
let filename = tmpdir // "source.vmx" in
|
||
|
- Ssh.download_file uri filename;
|
||
|
+ Ssh.download_file ~password ?port ~server ?user path filename;
|
||
|
Parse_vmx.parse_file filename in
|
||
|
|
||
|
let name =
|
||
|
@@ -346,7 +359,10 @@ let parse_domain_from_vmx vmx_source =
|
||
|
warning (f_"no displayName key found in VMX file");
|
||
|
match vmx_source with
|
||
|
| File filename -> name_from_disk filename
|
||
|
- | SSH (_, uri) -> name_from_disk (Ssh.path_of_uri uri) in
|
||
|
+ | SSH (_, uri) ->
|
||
|
+ match uri.uri_path with
|
||
|
+ | None -> assert false (* checked by vmx_source_of_arg *)
|
||
|
+ | Some path -> name_from_disk path in
|
||
|
|
||
|
let genid =
|
||
|
(* See: https://lists.nongnu.org/archive/html/qemu-devel/2018-07/msg02019.html *)
|
||
|
diff --git a/input/ssh.ml b/input/ssh.ml
|
||
|
index 63ffeb12..127e818c 100644
|
||
|
--- a/input/ssh.ml
|
||
|
+++ b/input/ssh.ml
|
||
|
@@ -22,29 +22,19 @@ open Common_gettext.Gettext
|
||
|
|
||
|
open Printf
|
||
|
|
||
|
-(* Return various fields from the URI. The checks in vmx_source_of_arg
|
||
|
- * should ensure that none of these assertions fail.
|
||
|
- *)
|
||
|
-let port_of_uri { Xml.uri_port } =
|
||
|
- match uri_port with i when i <= 0 -> None | i -> Some i
|
||
|
-let server_of_uri { Xml.uri_server } =
|
||
|
- match uri_server with None -> assert false | Some s -> s
|
||
|
-let path_of_uri { Xml.uri_path } =
|
||
|
- match uri_path with None -> assert false | Some p -> p
|
||
|
-
|
||
|
(* 'scp' a remote file into a local file. *)
|
||
|
-let download_file uri output =
|
||
|
+let download_file ~password:_ ?port ~server ?user path output =
|
||
|
let cmd =
|
||
|
sprintf "scp%s%s %s%s:%s %s"
|
||
|
(if verbose () then "" else " -q")
|
||
|
- (match port_of_uri uri with
|
||
|
+ (match port with
|
||
|
| None -> ""
|
||
|
- | Some port -> sprintf " -P %d" port)
|
||
|
- (match uri.Xml.uri_user with
|
||
|
+ | Some port -> sprintf " -P %s" port)
|
||
|
+ (match user with
|
||
|
| None -> ""
|
||
|
| Some user -> quote user ^ "@")
|
||
|
- (quote (server_of_uri uri))
|
||
|
- (quote (path_of_uri uri))
|
||
|
+ (quote server)
|
||
|
+ (quote path)
|
||
|
(quote output) in
|
||
|
if verbose () then
|
||
|
eprintf "%s\n%!" cmd;
|
||
|
@@ -53,16 +43,16 @@ let download_file uri output =
|
||
|
see earlier error messages")
|
||
|
|
||
|
(* Test if [path] exists on the remote server. *)
|
||
|
-let remote_file_exists uri path =
|
||
|
+let remote_file_exists ~password:_ ?port ~server ?user path =
|
||
|
let cmd =
|
||
|
sprintf "ssh%s %s%s test -f %s"
|
||
|
- (match port_of_uri uri with
|
||
|
+ (match port with
|
||
|
| None -> ""
|
||
|
- | Some port -> sprintf " -p %d" port)
|
||
|
- (match uri.Xml.uri_user with
|
||
|
+ | Some port -> sprintf " -p %s" port)
|
||
|
+ (match user with
|
||
|
| None -> ""
|
||
|
| Some user -> quote user ^ "@")
|
||
|
- (quote (server_of_uri uri))
|
||
|
+ (quote server)
|
||
|
(* Double quoting is necessary for 'ssh', first to protect
|
||
|
* from the local shell, second to protect from the remote
|
||
|
* shell. https://github.com/libguestfs/virt-v2v/issues/35#issuecomment-1741730963
|
||
|
diff --git a/input/ssh.mli b/input/ssh.mli
|
||
|
index 62e78bd3..1f39cd1b 100644
|
||
|
--- a/input/ssh.mli
|
||
|
+++ b/input/ssh.mli
|
||
|
@@ -18,16 +18,15 @@
|
||
|
|
||
|
(** Wrappers for finding and downloading remote files over ssh. *)
|
||
|
|
||
|
-val path_of_uri : Xml.uri -> string
|
||
|
-val server_of_uri : Xml.uri -> string
|
||
|
-val port_of_uri : Xml.uri -> int option
|
||
|
+(** [remote_file_exists password ?port server ?user path]
|
||
|
+ checks that [path] exists on the remote server. *)
|
||
|
+val remote_file_exists : password:Nbdkit_ssh.password ->
|
||
|
+ ?port:string -> server:string -> ?user:string ->
|
||
|
+ string -> bool
|
||
|
|
||
|
-(** [remote_file_exists ssh_uri path] checks that [path] exists
|
||
|
- on the remote server [ssh_uri] (note any path inside [ssh_uri]
|
||
|
- is ignored). *)
|
||
|
-val remote_file_exists : Xml.uri -> string -> bool
|
||
|
-
|
||
|
-(** [download_file ssh_uri output]
|
||
|
- uses scp to copy the single remote file at [ssh_uri] to
|
||
|
+(** [download_file password ?port server ?user path output]
|
||
|
+ uses scp to copy the single remote file at [path] to
|
||
|
the local file called [output]. *)
|
||
|
-val download_file : Xml.uri -> string -> unit
|
||
|
+val download_file : password:Nbdkit_ssh.password ->
|
||
|
+ ?port:string -> server:string -> ?user:string -> string ->
|
||
|
+ string -> unit
|