mrc0mmand / rpms / libguestfs

Forked from rpms/libguestfs 3 years ago
Clone

Blame SOURCES/0036-v2v-Add-general-mechanism-for-input-and-output-optio.patch

e9bfca
From 390f01ad72c9846a71d721d68ddab4535c77bb4d Mon Sep 17 00:00:00 2001
e9bfca
From: "Richard W.M. Jones" <rjones@redhat.com>
e9bfca
Date: Thu, 22 Mar 2018 10:29:23 +0000
e9bfca
Subject: [PATCH] v2v: Add general mechanism for input and output options
e9bfca
 (-io/-oo).
e9bfca
e9bfca
Currently we have a bunch of ad hoc options like --vddk* and --vdsm*
e9bfca
(and proposed to add --rhv*) to handle extra parameters for input and
e9bfca
output modes/transports.  This complicates the command line parsing
e9bfca
and also the clarity of the command line (becauseit's not very obvious
e9bfca
which options apply to which side of the conversion).
e9bfca
e9bfca
Replace these with a general mechanism for handling input and output
e9bfca
options.
e9bfca
e9bfca
Thus (for example):
e9bfca
e9bfca
  --vddk-thumbprint=...   becomes   -io vddk-thumbprint=...
e9bfca
  --vdsm-compat=0.10                -oo vdsm-compat=0.10
e9bfca
e9bfca
The responsibility for parsing input and output options moves into the
e9bfca
input and output drivers.
e9bfca
e9bfca
This improves error checking so it's harder now for wrong flags to be
e9bfca
included on the command line when they don't apply to the current mode.
e9bfca
e9bfca
The old option names are preserved for compatibility.
e9bfca
e9bfca
(cherry picked from commit 6327e716cdd2f161bc639733f216a3a29d26ad3c)
e9bfca
---
e9bfca
 v2v/Makefile.am                  |   4 +
e9bfca
 v2v/cmdline.ml                   | 229 ++++++++++++++-------------
e9bfca
 v2v/input_libvirt.ml             |   4 +-
e9bfca
 v2v/input_libvirt.mli            |   4 +-
e9bfca
 v2v/input_libvirt_vddk.ml        | 112 +++++++++-----
e9bfca
 v2v/input_libvirt_vddk.mli       |  16 +-
e9bfca
 v2v/output_vdsm.ml               |  79 +++++++++-
e9bfca
 v2v/output_vdsm.mli              |  13 +-
e9bfca
 v2v/test-v2v-docs.sh             |  32 +++-
e9bfca
 v2v/test-v2v-it-vddk-io-query.sh |  38 +++++
e9bfca
 v2v/test-v2v-o-vdsm-oo-query.sh  |  38 +++++
e9bfca
 v2v/test-v2v-o-vdsm-options.sh   |  16 +-
e9bfca
 v2v/virt-v2v.pod                 | 258 ++++++++++++++++---------------
e9bfca
 13 files changed, 531 insertions(+), 312 deletions(-)
e9bfca
 create mode 100755 v2v/test-v2v-it-vddk-io-query.sh
e9bfca
 create mode 100755 v2v/test-v2v-o-vdsm-oo-query.sh
e9bfca
e9bfca
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
e9bfca
index 424530b1d..5fcfeadba 100644
e9bfca
--- a/v2v/Makefile.am
e9bfca
+++ b/v2v/Makefile.am
e9bfca
@@ -307,6 +307,8 @@ TESTS = \
e9bfca
 	test-v2v-i-ova-tar.sh \
e9bfca
 	test-v2v-i-ova-two-disks.sh \
e9bfca
 	test-v2v-i-vmx.sh \
e9bfca
+	test-v2v-it-vddk-io-query.sh \
e9bfca
+	test-v2v-o-vdsm-oo-query.sh \
e9bfca
 	test-v2v-bad-networks-and-bridges.sh
e9bfca
 
e9bfca
 if HAVE_LIBVIRT
e9bfca
@@ -468,6 +470,7 @@ EXTRA_DIST += \
e9bfca
 	test-v2v-i-vmx-3.vmx \
e9bfca
 	test-v2v-i-vmx-4.vmx \
e9bfca
 	test-v2v-i-vmx-5.vmx \
e9bfca
+	test-v2v-it-vddk-io-query.sh \
e9bfca
 	test-v2v-machine-readable.sh \
e9bfca
 	test-v2v-networks-and-bridges-expected.xml \
e9bfca
 	test-v2v-networks-and-bridges.sh \
e9bfca
@@ -478,6 +481,7 @@ EXTRA_DIST += \
e9bfca
 	test-v2v-o-null.sh \
e9bfca
 	test-v2v-o-qemu.sh \
e9bfca
 	test-v2v-o-rhv.sh \
e9bfca
+	test-v2v-o-vdsm-oo-query.sh \
e9bfca
 	test-v2v-o-vdsm-options.sh \
e9bfca
 	test-v2v-oa-option.sh \
e9bfca
 	test-v2v-of-option.sh \
e9bfca
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
e9bfca
index 9bd0e8afc..c9b859dd6 100644
e9bfca
--- a/v2v/cmdline.ml
e9bfca
+++ b/v2v/cmdline.ml
e9bfca
@@ -65,24 +65,6 @@ let parse_cmdline () =
e9bfca
   let output_password = ref None in
e9bfca
   let output_storage = ref None in
e9bfca
   let password_file = ref None in
e9bfca
-  let vddk_config = ref None in
e9bfca
-  let vddk_cookie = ref None in
e9bfca
-  let vddk_libdir = ref None in
e9bfca
-  let vddk_nfchostport = ref None in
e9bfca
-  let vddk_port = ref None in
e9bfca
-  let vddk_snapshot = ref None in
e9bfca
-  let vddk_thumbprint = ref None in
e9bfca
-  let vddk_transports = ref None in
e9bfca
-  let vddk_vimapiver = ref None in
e9bfca
-  let vdsm_vm_uuid = ref None in
e9bfca
-  let vdsm_ovf_output = ref None in (* default "." *)
e9bfca
-
e9bfca
-  let vdsm_compat = ref "0.10" in
e9bfca
-  let set_vdsm_compat s = vdsm_compat := s in
e9bfca
-
e9bfca
-  let vdsm_ovf_flavour = ref Create_ovf.RHVExportStorageDomain in
e9bfca
-  let set_vdsm_ovf_flavour arg =
e9bfca
-    vdsm_ovf_flavour := Create_ovf.ovf_flavour_of_string arg in
e9bfca
 
e9bfca
   let set_string_option_once optname optref arg =
e9bfca
     match !optref with
e9bfca
@@ -106,6 +88,15 @@ let parse_cmdline () =
e9bfca
       error (f_"unknown -i option: %s") s
e9bfca
   in
e9bfca
 
e9bfca
+  let input_options = ref [] in
e9bfca
+  let set_input_option_compat k v =
e9bfca
+    input_options := (k, v) :: !input_options
e9bfca
+  in
e9bfca
+  let set_input_option option =
e9bfca
+    let k, v = String.split "=" option in
e9bfca
+    set_input_option_compat k v
e9bfca
+  in
e9bfca
+
e9bfca
   let network_map = ref NetworkMap.empty in
e9bfca
   let add_network, add_bridge =
e9bfca
     let add flag name t str =
e9bfca
@@ -159,6 +150,15 @@ let parse_cmdline () =
e9bfca
       error (f_"unknown -oa option: %s") s
e9bfca
   in
e9bfca
 
e9bfca
+  let output_options = ref [] in
e9bfca
+  let set_output_option_compat k v =
e9bfca
+    output_options := (k, v) :: !output_options
e9bfca
+  in
e9bfca
+  let set_output_option option =
e9bfca
+    let k, v = String.split "=" option in
e9bfca
+    set_output_option_compat k v
e9bfca
+  in
e9bfca
+
e9bfca
   let root_choice = ref AskRoot in
e9bfca
   let set_root_choice = function
e9bfca
     | "ask" -> root_choice := AskRoot
e9bfca
@@ -169,12 +169,6 @@ let parse_cmdline () =
e9bfca
       error (f_"unknown --root option: %s") s
e9bfca
   in
e9bfca
 
e9bfca
-  let vdsm_image_uuids = ref [] in
e9bfca
-  let add_vdsm_image_uuid s = List.push_front s vdsm_image_uuids in
e9bfca
-
e9bfca
-  let vdsm_vol_uuids = ref [] in
e9bfca
-  let add_vdsm_vol_uuid s = List.push_front s vdsm_vol_uuids in
e9bfca
-
e9bfca
   let vmtype_warning _ =
e9bfca
     warning (f_"the --vmtype option has been removed and now does nothing")
e9bfca
   in
e9bfca
@@ -198,6 +192,8 @@ let parse_cmdline () =
e9bfca
                                     s_"Libvirt URI";
e9bfca
     [ M"if" ],       Getopt.String ("format", set_string_option_once "-if" input_format),
e9bfca
                                     s_"Input format (for -i disk)";
e9bfca
+    [ M"io" ],       Getopt.String ("option[=value]", set_input_option),
e9bfca
+                                    s_"Set option for input mode";
e9bfca
     [ M"it" ],       Getopt.String ("transport", set_string_option_once "-it" input_transport),
e9bfca
                                     s_"Input transport";
e9bfca
     [ L"in-place" ], Getopt.Set in_place, Getopt.hidden_option_description;
e9bfca
@@ -219,6 +215,8 @@ let parse_cmdline () =
e9bfca
                                     s_"Set output format";
e9bfca
     [ M"on" ],       Getopt.String ("name", set_string_option_once "-on" output_name),
e9bfca
                                     s_"Rename guest when converting";
e9bfca
+    [ M"oo" ],       Getopt.String ("option[=value]", set_output_option),
e9bfca
+                                    s_"Set option for output mode";
e9bfca
     [ M"op" ],       Getopt.String ("filename", set_string_option_once "-op" output_password),
e9bfca
                                     s_"Use password from file to connect to output hypervisor";
e9bfca
     [ M"os" ],       Getopt.String ("storage", set_string_option_once "-os" output_storage),
e9bfca
@@ -229,36 +227,36 @@ let parse_cmdline () =
e9bfca
                                     s_"Print source and stop";
e9bfca
     [ L"root" ],     Getopt.String ("ask|... ", set_root_choice),
e9bfca
                                     s_"How to choose root filesystem";
e9bfca
-    [ L"vddk-config" ], Getopt.String ("filename", set_string_option_once "--vddk-config" vddk_config),
e9bfca
-                                    s_"Set VDDK config file";
e9bfca
-    [ L"vddk-cookie" ], Getopt.String ("cookie", set_string_option_once "--vddk-cookie" vddk_cookie),
e9bfca
-                                    s_"Set VDDK cookie";
e9bfca
-    [ L"vddk-libdir" ], Getopt.String ("libdir", set_string_option_once "--vddk-libdir" vddk_libdir),
e9bfca
-                                    s_"Set VDDK library parent directory";
e9bfca
-    [ L"vddk-nfchostport" ], Getopt.String ("nfchostport", set_string_option_once "--vddk-nfchostport" vddk_nfchostport),
e9bfca
-                                    s_"Set VDDK nfchostport";
e9bfca
-    [ L"vddk-port" ], Getopt.String ("port", set_string_option_once "--vddk-port" vddk_port),
e9bfca
-                                    s_"Set VDDK port";
e9bfca
-    [ L"vddk-snapshot" ], Getopt.String ("snapshot-moref", set_string_option_once "--vddk-snapshot" vddk_snapshot),
e9bfca
-                                    s_"Set VDDK snapshot";
e9bfca
-    [ L"vddk-thumbprint" ], Getopt.String ("thumbprint", set_string_option_once "--vddk-thumbprint" vddk_thumbprint),
e9bfca
-                                    s_"Set VDDK thumbprint";
e9bfca
-    [ L"vddk-transports" ], Getopt.String ("transports", set_string_option_once "--vddk-transports" vddk_transports),
e9bfca
-                                    s_"Set VDDK transports";
e9bfca
-    [ L"vddk-vimapiver" ], Getopt.String ("apiver", set_string_option_once "--vddk-vimapiver" vddk_vimapiver),
e9bfca
-                                    s_"Set VDDK vimapiver";
e9bfca
-    [ L"vdsm-compat" ], Getopt.Symbol ("0.10|1.1", ["0.10"; "1.1"], set_vdsm_compat),
e9bfca
-                                    s_"Write qcow2 with compat=0.10|1.1";
e9bfca
-    [ L"vdsm-image-uuid" ], Getopt.String ("uuid", add_vdsm_image_uuid),
e9bfca
-                                    s_"Output image UUID(s)";
e9bfca
-    [ L"vdsm-vol-uuid" ], Getopt.String ("uuid", add_vdsm_vol_uuid),
e9bfca
-                                    s_"Output vol UUID(s)";
e9bfca
-    [ L"vdsm-vm-uuid" ], Getopt.String ("uuid", set_string_option_once "--vdsm-vm-uuid" vdsm_vm_uuid),
e9bfca
-                                    s_"Output VM UUID";
e9bfca
-    [ L"vdsm-ovf-output" ], Getopt.String ("-", set_string_option_once "--vdsm-ovf-output" vdsm_ovf_output),
e9bfca
-                                    s_"Output OVF file";
e9bfca
-    [ L"vdsm-ovf-flavour" ], Getopt.Symbol (ovf_flavours_str, Create_ovf.ovf_flavours, set_vdsm_ovf_flavour),
e9bfca
-                                    s_"Set the type of generated OVF (default rhvexp)";
e9bfca
+    [ L"vddk-config" ], Getopt.String ("filename", set_input_option_compat "vddk-config"),
e9bfca
+                                    s_"Same as ‘-io vddk-config=filename’";
e9bfca
+    [ L"vddk-cookie" ], Getopt.String ("cookie", set_input_option_compat "vddk-cookie"),
e9bfca
+                                    s_"Same as ‘-io vddk-cookie=filename’";
e9bfca
+    [ L"vddk-libdir" ], Getopt.String ("libdir", set_input_option_compat "vddk-libdir"),
e9bfca
+                                    s_"Same as ‘-io vddk-libdir=libdir’";
e9bfca
+    [ L"vddk-nfchostport" ], Getopt.String ("nfchostport", set_input_option_compat "vddk-nfchostport"),
e9bfca
+                                    s_"Same as ‘-io vddk-nfchostport=nfchostport’";
e9bfca
+    [ L"vddk-port" ], Getopt.String ("port", set_input_option_compat "vddk-port"),
e9bfca
+                                    s_"Same as ‘-io vddk-port=port’";
e9bfca
+    [ L"vddk-snapshot" ], Getopt.String ("snapshot-moref", set_input_option_compat "vddk-snapshot"),
e9bfca
+                                    s_"Same as ‘-io vddk-snapshot=snapshot-moref’";
e9bfca
+    [ L"vddk-thumbprint" ], Getopt.String ("thumbprint", set_input_option_compat "vddk-thumbprint"),
e9bfca
+                                    s_"Same as ‘-io vddk-thumbprint=thumbprint’";
e9bfca
+    [ L"vddk-transports" ], Getopt.String ("transports", set_input_option_compat "vddk-transports"),
e9bfca
+                                    s_"Same as ‘-io vddk-transports=transports’";
e9bfca
+    [ L"vddk-vimapiver" ], Getopt.String ("apiver", set_input_option_compat "vddk-vimapiver"),
e9bfca
+                                    s_"Same as ‘-io vddk-vimapiver=apiver’";
e9bfca
+    [ L"vdsm-compat" ], Getopt.String ("0.10|1.1", set_output_option_compat "vdsm-compat"),
e9bfca
+                                    s_"Same as ‘-oo vdsm-compat=0.10|1.1’";
e9bfca
+    [ L"vdsm-image-uuid" ], Getopt.String ("uuid", set_output_option_compat "vdsm-image-uuid"),
e9bfca
+                                    s_"Same as ‘-oo vdsm-image-uuid=uuid’";
e9bfca
+    [ L"vdsm-vol-uuid" ], Getopt.String ("uuid", set_output_option_compat "vdsm-vol-uuid"),
e9bfca
+                                    s_"Same as ‘-oo vdsm-vol-uuid=uuid’";
e9bfca
+    [ L"vdsm-vm-uuid" ], Getopt.String ("uuid", set_output_option_compat "vdsm-vm-uuid"),
e9bfca
+                                    s_"Same as ‘-oo vdsm-vm-uuid=uuid’";
e9bfca
+    [ L"vdsm-ovf-output" ], Getopt.String ("dir", set_output_option_compat "vdsm-ovf-output"),
e9bfca
+                                    s_"Same as ‘-oo vdsm-ovf-output=dir’";
e9bfca
+    [ L"vdsm-ovf-flavour" ], Getopt.String (ovf_flavours_str, set_output_option_compat "vdsm-ovf-flavour"),
e9bfca
+                                    s_"Same as ‘-oo vdsm-ovf-flavour=flavour’";
e9bfca
     [ L"vmtype" ],   Getopt.String ("-", vmtype_warning),
e9bfca
                                     s_"Ignored for backwards compatibility";
e9bfca
   ] in
e9bfca
@@ -297,6 +295,7 @@ read the man page virt-v2v(1).
e9bfca
   let input_conn = !input_conn in
e9bfca
   let input_format = !input_format in
e9bfca
   let input_mode = !input_mode in
e9bfca
+  let input_options = List.rev !input_options in
e9bfca
   let input_transport =
e9bfca
     match !input_transport with
e9bfca
     | None -> None
e9bfca
@@ -315,28 +314,13 @@ read the man page virt-v2v(1).
e9bfca
   let output_format = !output_format in
e9bfca
   let output_mode = !output_mode in
e9bfca
   let output_name = !output_name in
e9bfca
+  let output_options = List.rev !output_options in
e9bfca
   let output_password = !output_password in
e9bfca
   let output_storage = !output_storage in
e9bfca
   let password_file = !password_file in
e9bfca
   let print_source = !print_source in
e9bfca
   let qemu_boot = !qemu_boot in
e9bfca
   let root_choice = !root_choice in
e9bfca
-  let vddk_options =
e9bfca
-      { Input_libvirt_vddk.vddk_config = !vddk_config;
e9bfca
-        vddk_cookie = !vddk_cookie;
e9bfca
-        vddk_libdir = !vddk_libdir;
e9bfca
-        vddk_nfchostport = !vddk_nfchostport;
e9bfca
-        vddk_port = !vddk_port;
e9bfca
-        vddk_snapshot = !vddk_snapshot;
e9bfca
-        vddk_thumbprint = !vddk_thumbprint;
e9bfca
-        vddk_transports = !vddk_transports;
e9bfca
-        vddk_vimapiver = !vddk_vimapiver } in
e9bfca
-  let vdsm_compat = !vdsm_compat in
e9bfca
-  let vdsm_image_uuids = List.rev !vdsm_image_uuids in
e9bfca
-  let vdsm_vol_uuids = List.rev !vdsm_vol_uuids in
e9bfca
-  let vdsm_vm_uuid = !vdsm_vm_uuid in
e9bfca
-  let vdsm_ovf_output = Option.default "." !vdsm_ovf_output in
e9bfca
-  let vdsm_ovf_flavour = !vdsm_ovf_flavour in
e9bfca
 
e9bfca
   (* No arguments and machine-readable mode?  Print out some facts
e9bfca
    * about what this binary supports.
e9bfca
@@ -349,6 +333,7 @@ read the man page virt-v2v(1).
e9bfca
     printf "vddk\n";
e9bfca
     printf "colours-option\n";
e9bfca
     printf "vdsm-compat-option\n";
e9bfca
+    printf "io/oo\n";
e9bfca
     List.iter (printf "input:%s\n") (Modules_list.input_modules ());
e9bfca
     List.iter (printf "output:%s\n") (Modules_list.output_modules ());
e9bfca
     List.iter (printf "convert:%s\n") (Modules_list.convert_modules ());
e9bfca
@@ -356,6 +341,65 @@ read the man page virt-v2v(1).
e9bfca
     exit 0
e9bfca
   );
e9bfca
 
e9bfca
+  (* Input transport affects whether some input options should or
e9bfca
+   * should not be used.
e9bfca
+   *)
e9bfca
+  let input_transport =
e9bfca
+    let is_query = input_options = ["?", ""] in
e9bfca
+    let no_options () =
e9bfca
+      if is_query then (
e9bfca
+        printf (f_"No -io (input options) are supported with this input transport.\n");
e9bfca
+        exit 0
e9bfca
+      )
e9bfca
+      else if input_options <> [] then
e9bfca
+        error (f_"no -io (input options) are allowed here");
e9bfca
+    in
e9bfca
+    match input_transport with
e9bfca
+    | None -> no_options (); None
e9bfca
+    | Some `SSH -> no_options (); Some `SSH
e9bfca
+    | Some `VDDK ->
e9bfca
+       if is_query then (
e9bfca
+         Input_libvirt_vddk.print_input_options ();
e9bfca
+         exit 0
e9bfca
+       )
e9bfca
+       else (
e9bfca
+         let vddk_options =
e9bfca
+           Input_libvirt_vddk.parse_input_options input_options in
e9bfca
+         Some (`VDDK vddk_options)
e9bfca
+       ) in
e9bfca
+
e9bfca
+  (* Output mode affects whether some output options should or
e9bfca
+   * should not be used.
e9bfca
+   *)
e9bfca
+  let output_mode =
e9bfca
+    let is_query = output_options = ["?", ""] in
e9bfca
+    let no_options () =
e9bfca
+      if is_query then (
e9bfca
+        printf (f_"No -oo (output options) are supported in this output mode.\n");
e9bfca
+        exit 0
e9bfca
+      )
e9bfca
+      else if output_options <> [] then
e9bfca
+        error (f_"no -oo (output options) are allowed here");
e9bfca
+    in
e9bfca
+    match output_mode with
e9bfca
+    | `Not_set -> no_options (); `Not_set
e9bfca
+    | `Glance -> no_options (); `Glance
e9bfca
+    | `Libvirt -> no_options (); `Libvirt
e9bfca
+    | `Local -> no_options (); `Local
e9bfca
+    | `Null -> no_options (); `Null
e9bfca
+    | `RHV -> no_options (); `RHV
e9bfca
+    | `QEmu -> no_options (); `QEmu
e9bfca
+    | `VDSM ->
e9bfca
+       if is_query then (
e9bfca
+         Output_vdsm.print_output_options ();
e9bfca
+         exit 0
e9bfca
+       )
e9bfca
+       else (
e9bfca
+         let vdsm_options =
e9bfca
+           Output_vdsm.parse_output_options output_options in
e9bfca
+         `VDSM vdsm_options
e9bfca
+       ) in
e9bfca
+
e9bfca
   (* Parse out the password from the password file. *)
e9bfca
   let password =
e9bfca
     match password_file with
e9bfca
@@ -364,27 +408,6 @@ read the man page virt-v2v(1).
e9bfca
       let password = read_first_line_from_file filename in
e9bfca
       Some password in
e9bfca
 
e9bfca
-  (* Input transport affects whether some parameters should or
e9bfca
-   * should not be used.
e9bfca
-   *)
e9bfca
-  (match input_transport with
e9bfca
-   | None
e9bfca
-   | Some `SSH ->
e9bfca
-      if !vddk_config <> None ||
e9bfca
-         !vddk_cookie <> None ||
e9bfca
-         !vddk_libdir <> None ||
e9bfca
-         !vddk_nfchostport <> None ||
e9bfca
-         !vddk_port <> None ||
e9bfca
-         !vddk_snapshot <> None ||
e9bfca
-         !vddk_thumbprint <> None ||
e9bfca
-         !vddk_transports <> None ||
e9bfca
-         !vddk_vimapiver <> None then
e9bfca
-        error (f_"‘--vddk-*’ options should only be used when conversion via the nbdkit VDDK plugin has been enabled, ie. using ‘-it vddk’.")
e9bfca
-   | Some `VDDK ->
e9bfca
-      if !vddk_thumbprint = None then
e9bfca
-        error (f_"‘--vddk-thumbprint’ is required when using ‘-it vddk’.")
e9bfca
-  );
e9bfca
-
e9bfca
   (* Parsing of the argument(s) depends on the input mode. *)
e9bfca
   let input =
e9bfca
     match input_mode with
e9bfca
@@ -410,11 +433,10 @@ read the man page virt-v2v(1).
e9bfca
       let input_transport =
e9bfca
         match input_transport with
e9bfca
         | None -> None
e9bfca
-        | Some `VDDK -> Some `VDDK
e9bfca
+        | (Some (`VDDK _) as vddk) -> vddk
e9bfca
         | Some `SSH ->
e9bfca
            error (f_"only ‘-it vddk’ can be used here") in
e9bfca
-      Input_libvirt.input_libvirt vddk_options password
e9bfca
-                                  input_conn input_transport guest
e9bfca
+      Input_libvirt.input_libvirt password input_conn input_transport guest
e9bfca
 
e9bfca
     | `LibvirtXML ->
e9bfca
       (* -i libvirtxml: Expecting a filename (XML file). *)
e9bfca
@@ -445,7 +467,7 @@ read the man page virt-v2v(1).
e9bfca
         match input_transport with
e9bfca
         | None -> None
e9bfca
         | Some `SSH -> Some `SSH
e9bfca
-        | Some `VDDK ->
e9bfca
+        | Some (`VDDK _) ->
e9bfca
            error (f_"only ‘-it ssh’ can be used here") in
e9bfca
       Input_vmx.input_vmx input_transport arg in
e9bfca
 
e9bfca
@@ -549,7 +571,7 @@ read the man page virt-v2v(1).
e9bfca
       Output_rhv.output_rhv os output_alloc,
e9bfca
       output_format, output_alloc
e9bfca
 
e9bfca
-    | `VDSM ->
e9bfca
+    | `VDSM vdsm_options ->
e9bfca
       if output_password <> None then
e9bfca
         error_option_cannot_be_used_in_output_mode "vdsm" "-op";
e9bfca
       let os =
e9bfca
@@ -559,21 +581,6 @@ read the man page virt-v2v(1).
e9bfca
         | Some d -> d in
e9bfca
       if qemu_boot then
e9bfca
         error_option_cannot_be_used_in_output_mode "vdsm" "--qemu-boot";
e9bfca
-      let vdsm_vm_uuid =
e9bfca
-        match vdsm_vm_uuid with
e9bfca
-        | None ->
e9bfca
-           error (f_"-o vdsm: --vdsm-image-uuid was not specified")
e9bfca
-        | Some s -> s in
e9bfca
-      if vdsm_image_uuids = [] || vdsm_vol_uuids = [] then
e9bfca
-        error (f_"-o vdsm: either --vdsm-vol-uuid or --vdsm-vm-uuid was not specified");
e9bfca
-      let vdsm_options = {
e9bfca
-        Output_vdsm.image_uuids = vdsm_image_uuids;
e9bfca
-        vol_uuids = vdsm_vol_uuids;
e9bfca
-        vm_uuid = vdsm_vm_uuid;
e9bfca
-        ovf_output = vdsm_ovf_output;
e9bfca
-        compat = vdsm_compat;
e9bfca
-        ovf_flavour = vdsm_ovf_flavour;
e9bfca
-      } in
e9bfca
       Output_vdsm.output_vdsm os vdsm_options output_alloc,
e9bfca
       output_format, output_alloc in
e9bfca
 
e9bfca
diff --git a/v2v/input_libvirt.ml b/v2v/input_libvirt.ml
e9bfca
index 25c81b924..377257dc2 100644
e9bfca
--- a/v2v/input_libvirt.ml
e9bfca
+++ b/v2v/input_libvirt.ml
e9bfca
@@ -27,7 +27,7 @@ open Types
e9bfca
 open Utils
e9bfca
 
e9bfca
 (* Choose the right subclass based on the URI. *)
e9bfca
-let input_libvirt vddk_options password libvirt_uri input_transport guest =
e9bfca
+let input_libvirt password libvirt_uri input_transport guest =
e9bfca
   match libvirt_uri with
e9bfca
   | None ->
e9bfca
     Input_libvirt_other.input_libvirt_other password libvirt_uri guest
e9bfca
@@ -53,7 +53,7 @@ let input_libvirt vddk_options password libvirt_uri input_transport guest =
e9bfca
          password libvirt_uri parsed_uri server guest
e9bfca
 
e9bfca
     (* vCenter or ESXi using nbdkit vddk plugin *)
e9bfca
-    | Some server, Some ("esx"|"gsx"|"vpx"), Some `VDDK ->
e9bfca
+    | Some server, Some ("esx"|"gsx"|"vpx"), Some (`VDDK vddk_options) ->
e9bfca
        Input_libvirt_vddk.input_libvirt_vddk vddk_options password
e9bfca
                                              libvirt_uri parsed_uri guest
e9bfca
 
e9bfca
diff --git a/v2v/input_libvirt.mli b/v2v/input_libvirt.mli
e9bfca
index 6f9162482..08824bb67 100644
e9bfca
--- a/v2v/input_libvirt.mli
e9bfca
+++ b/v2v/input_libvirt.mli
e9bfca
@@ -18,7 +18,7 @@
e9bfca
 
e9bfca
 (** [-i libvirt] source. *)
e9bfca
 
e9bfca
-val input_libvirt : Input_libvirt_vddk.vddk_options -> string option -> string option -> [`VDDK] option -> string -> Types.input
e9bfca
-(** [input_libvirt vddk_options password libvirt_uri input_transport guest]
e9bfca
+val input_libvirt : string option -> string option -> [`VDDK of Input_libvirt_vddk.vddk_options] option -> string -> Types.input
e9bfca
+(** [input_libvirt password libvirt_uri input_transport guest]
e9bfca
     creates and returns a new {!Types.input} object specialized for reading
e9bfca
     input from libvirt sources. *)
e9bfca
diff --git a/v2v/input_libvirt_vddk.ml b/v2v/input_libvirt_vddk.ml
e9bfca
index a53f3e71d..0b3ed7af9 100644
e9bfca
--- a/v2v/input_libvirt_vddk.ml
e9bfca
+++ b/v2v/input_libvirt_vddk.ml
e9bfca
@@ -33,22 +33,73 @@ open Xpath_helpers
e9bfca
 
e9bfca
 open Printf
e9bfca
 
e9bfca
-type vddk_options = {
e9bfca
-    vddk_config : string option;
e9bfca
-    vddk_cookie : string option;
e9bfca
-    vddk_libdir : string option;
e9bfca
-    vddk_nfchostport : string option;
e9bfca
-    vddk_port : string option;
e9bfca
-    vddk_snapshot : string option;
e9bfca
-    vddk_thumbprint : string option;
e9bfca
-    vddk_transports : string option;
e9bfca
-    vddk_vimapiver : string option;
e9bfca
-}
e9bfca
+type vddk_options = (string * string) list
e9bfca
+
e9bfca
+(* List of vddk-* input options. *)
e9bfca
+let vddk_option_keys =
e9bfca
+  [ "config";
e9bfca
+    "cookie";
e9bfca
+    "libdir";
e9bfca
+    "nfchostport";
e9bfca
+    "port";
e9bfca
+    "snapshot";
e9bfca
+    "thumbprint";
e9bfca
+    "transports";
e9bfca
+    "vimapiver" ]
e9bfca
+
e9bfca
+let print_input_options () =
e9bfca
+  printf (f_"Input options (-io) which can be used with -it vddk:
e9bfca
+
e9bfca
+  -io vddk-thumbprint=xx:xx:xx:...
e9bfca
+                               VDDK server thumbprint (required)
e9bfca
+
e9bfca
+All other settings are optional:
e9bfca
+
e9bfca
+  -io vddk-config=FILE         VDDK configuration file
e9bfca
+  -io vddk-cookie=COOKIE       VDDK cookie
e9bfca
+  -io vddk-libdir=LIBDIR       VDDK library parent directory
e9bfca
+  -io vddk-nfchostport=PORT    VDDK nfchostport
e9bfca
+  -io vddk-port=PORT           VDDK port
e9bfca
+  -io vddk-snapshot=SNAPSHOT-MOREF
e9bfca
+                               VDDK snapshot moref
e9bfca
+  -io vddk-transports=MODE:MODE:..
e9bfca
+                               VDDK transports
e9bfca
+  -io vddk-vimapiver=APIVER    VDDK vimapiver
e9bfca
+
e9bfca
+Refer to nbdkit-vddk-plugin(1) and the VDDK documentation for further
e9bfca
+information on these settings.
e9bfca
+")
e9bfca
+
e9bfca
+let parse_input_options options =
e9bfca
+  (* Check there are no options we don't understand.  Also removes
e9bfca
+   * the "vddk-" prefix from the internal list.
e9bfca
+   *)
e9bfca
+  let options =
e9bfca
+    List.map (
e9bfca
+      fun (key, value) ->
e9bfca
+        let error_invalid_key () =
e9bfca
+          error (f_"-it vddk: ‘-io %s’ is not a valid input option") key
e9bfca
+        in
e9bfca
+        if not (String.is_prefix key "vddk-") then error_invalid_key ();
e9bfca
+        let key = String.sub key 5 (String.length key-5) in
e9bfca
+        if not (List.mem key vddk_option_keys) then error_invalid_key ();
e9bfca
+
e9bfca
+        (key, value)
e9bfca
+    ) options in
e9bfca
+
e9bfca
+  (* Check no option appears twice. *)
e9bfca
+  let keys = List.map fst options in
e9bfca
+  if List.length keys <> List.length (List.sort_uniq keys) then
e9bfca
+    error (f_"-it vddk: duplicate -io options on the command line");
e9bfca
+
e9bfca
+  options
e9bfca
 
e9bfca
 (* Subclass specialized for handling VMware via nbdkit vddk plugin. *)
e9bfca
 class input_libvirt_vddk vddk_options password libvirt_uri parsed_uri guest =
e9bfca
   (* The VDDK path. *)
e9bfca
-  let libdir = vddk_options.vddk_libdir in
e9bfca
+  let libdir =
e9bfca
+    try Some (List.assoc "libdir" vddk_options)
e9bfca
+    with Not_found -> None in
e9bfca
 
e9bfca
   (* VDDK libraries are located under lib32/ or lib64/ relative to the
e9bfca
    * libdir.  Note this is unrelated to Linux multilib or multiarch.
e9bfca
@@ -68,7 +119,7 @@ class input_libvirt_vddk vddk_options password libvirt_uri parsed_uri guest =
e9bfca
      | None -> ()
e9bfca
      | Some libdir ->
e9bfca
         if not (is_directory libdir) then
e9bfca
-          error (f_"‘--vddk-libdir %s’ does not point to a directory.  See \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") libdir
e9bfca
+          error (f_"‘-io vddk-libdir=%s’ does not point to a directory.  See \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") libdir
e9bfca
     );
e9bfca
 
e9bfca
     (match library_path with
e9bfca
@@ -122,15 +173,15 @@ See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.")
e9bfca
       else
e9bfca
         error (f_"nbdkit VDDK plugin is not installed or not working.  It is required if you want to use VDDK.
e9bfca
 
e9bfca
-It looks like you did not set the right path in the ‘--vddk-libdir’ option, or your copy of the VDDK directory is incomplete.  There should be a library called ’<libdir>/%s/libvixDiskLib.so.?’.
e9bfca
+It looks like you did not set the right path in the ‘-io vddk-libdir’ option, or your copy of the VDDK directory is incomplete.  There should be a library called ’<libdir>/%s/libvixDiskLib.so.?’.
e9bfca
 
e9bfca
 See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") libNN
e9bfca
     )
e9bfca
   in
e9bfca
 
e9bfca
   let error_unless_thumbprint () =
e9bfca
-    if vddk_options.vddk_thumbprint = None then
e9bfca
-      error (f_"You must pass the ‘--vddk-thumbprint’ option with the SSL thumbprint of the VMware server.  To find the thumbprint, see the nbdkit-vddk-plugin(1) manual.  See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.")
e9bfca
+    if not (List.mem_assoc "thumbprint" vddk_options) then
e9bfca
+      error (f_"You must pass the ‘-io vddk-thumbprint’ option with the SSL thumbprint of the VMware server.  To find the thumbprint, see the nbdkit-vddk-plugin(1) manual.  See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.")
e9bfca
   in
e9bfca
 
e9bfca
   (* Check that nbdkit was compiled with SELinux support (for the
e9bfca
@@ -147,18 +198,6 @@ See also \"INPUT FROM VDDK\" in the virt-v2v(1) manual.") libNN
e9bfca
       error (f_"nbdkit was compiled without SELinux support.  You will have to recompile nbdkit with libselinux-devel installed, or else set SELinux to Permissive mode while doing the conversion.")
e9bfca
   in
e9bfca
 
e9bfca
-  (* List of passthrough parameters. *)
e9bfca
-  let vddk_passthrus =
e9bfca
-    [ "config",      (fun { vddk_config }      -> vddk_config);
e9bfca
-      "cookie",      (fun { vddk_cookie }      -> vddk_cookie);
e9bfca
-      "libdir",      (fun { vddk_libdir }      -> vddk_libdir);
e9bfca
-      "nfchostport", (fun { vddk_nfchostport } -> vddk_nfchostport);
e9bfca
-      "port",        (fun { vddk_port }        -> vddk_port);
e9bfca
-      "snapshot",    (fun { vddk_snapshot }    -> vddk_snapshot);
e9bfca
-      "thumbprint",  (fun { vddk_thumbprint }  -> vddk_thumbprint);
e9bfca
-      "transports",  (fun { vddk_transports }  -> vddk_transports);
e9bfca
-      "vimapiver",   (fun { vddk_vimapiver }   -> vddk_vimapiver) ] in
e9bfca
-
e9bfca
 object
e9bfca
   inherit input_libvirt password libvirt_uri guest as super
e9bfca
 
e9bfca
@@ -172,14 +211,9 @@ object
e9bfca
 
e9bfca
   method as_options =
e9bfca
     let pt_options =
e9bfca
-      String.concat "" (
e9bfca
-        List.map (
e9bfca
-          fun (name, get_field) ->
e9bfca
-            match get_field vddk_options with
e9bfca
-            | None -> ""
e9bfca
-            | Some field -> sprintf " --vddk-%s %s" name field
e9bfca
-        ) vddk_passthrus
e9bfca
-      ) in
e9bfca
+      String.concat ""
e9bfca
+                    (List.map (fun (k, v) ->
e9bfca
+                         sprintf " -io vddk-%s=%s" k v) vddk_options) in
e9bfca
     sprintf "%s -it vddk %s"
e9bfca
             super#as_options (* superclass prints "-i libvirt etc" *)
e9bfca
             pt_options
e9bfca
@@ -284,11 +318,7 @@ object
e9bfca
       add_arg (sprintf "vm=moref=%s" moref);
e9bfca
 
e9bfca
       (* The passthrough parameters. *)
e9bfca
-      List.iter (
e9bfca
-        fun (name, get_field) ->
e9bfca
-          Option.may (fun field -> add_arg (sprintf "%s=%s" name field))
e9bfca
-                     (get_field vddk_options)
e9bfca
-      ) vddk_passthrus;
e9bfca
+      List.iter (fun (k, v) -> add_arg (sprintf "%s=%s" k v)) vddk_options;
e9bfca
 
e9bfca
       get_args () in
e9bfca
 
e9bfca
diff --git a/v2v/input_libvirt_vddk.mli b/v2v/input_libvirt_vddk.mli
e9bfca
index c8606c72a..1cebba506 100644
e9bfca
--- a/v2v/input_libvirt_vddk.mli
e9bfca
+++ b/v2v/input_libvirt_vddk.mli
e9bfca
@@ -18,19 +18,13 @@
e9bfca
 
e9bfca
 (** [-i libvirt] when the source is VMware via nbdkit vddk plugin *)
e9bfca
 
e9bfca
-type vddk_options = {
e9bfca
-    vddk_config : string option;
e9bfca
-    vddk_cookie : string option;
e9bfca
-    vddk_libdir : string option;
e9bfca
-    vddk_nfchostport : string option;
e9bfca
-    vddk_port : string option;
e9bfca
-    vddk_snapshot : string option;
e9bfca
-    vddk_thumbprint : string option;
e9bfca
-    vddk_transports : string option;
e9bfca
-    vddk_vimapiver : string option;
e9bfca
-}
e9bfca
+type vddk_options
e9bfca
 (** Various options passed through to the nbdkit vddk plugin unmodified. *)
e9bfca
 
e9bfca
+val print_input_options : unit -> unit
e9bfca
+val parse_input_options : (string * string) list -> vddk_options
e9bfca
+(** Print and parse vddk -io options. *)
e9bfca
+
e9bfca
 val input_libvirt_vddk : vddk_options -> string option -> string option -> Xml.uri -> string -> Types.input
e9bfca
 (** [input_libvirt_vddk vddk_options password libvirt_uri parsed_uri guest]
e9bfca
     creates and returns a {!Types.input} object specialized for reading
e9bfca
diff --git a/v2v/output_vdsm.ml b/v2v/output_vdsm.ml
e9bfca
index b76a2e930..92b3fd122 100644
e9bfca
--- a/v2v/output_vdsm.ml
e9bfca
+++ b/v2v/output_vdsm.ml
e9bfca
@@ -35,23 +35,90 @@ type vdsm_options = {
e9bfca
   ovf_flavour : Create_ovf.ovf_flavour;
e9bfca
 }
e9bfca
 
e9bfca
+let ovf_flavours_str = String.concat "|" Create_ovf.ovf_flavours
e9bfca
+
e9bfca
+let print_output_options () =
e9bfca
+  printf (f_"Output options (-oo) which can be used with -o vdsm:
e9bfca
+
e9bfca
+  -oo vdsm-compat=0.10|1.1     Write qcow2 with compat=0.10|1.1
e9bfca
+                                   (default: 0.10)
e9bfca
+  -oo vdsm-vm-uuid=UUID        VM UUID (required)
e9bfca
+  -oo vdsm-ovf-output=DIR      OVF metadata directory (required)
e9bfca
+  -oo vdsm-ovf-flavour=%s
e9bfca
+                               Set the type of generated OVF (default: rhvexp)
e9bfca
+
e9bfca
+For each disk you must supply one of each of these options:
e9bfca
+
e9bfca
+  -oo vdsm-image-uuid=UUID     Image directory UUID
e9bfca
+  -oo vdsm-vol-uuid=UUID       Disk volume UUID
e9bfca
+") ovf_flavours_str
e9bfca
+
e9bfca
+let parse_output_options options =
e9bfca
+  let vm_uuid = ref None in
e9bfca
+  let ovf_output = ref None in (* default "." *)
e9bfca
+  let compat = ref "0.10" in
e9bfca
+  let ovf_flavour = ref Create_ovf.RHVExportStorageDomain in
e9bfca
+  let image_uuids = ref [] in
e9bfca
+  let vol_uuids = ref [] in
e9bfca
+
e9bfca
+  List.iter (
e9bfca
+    function
e9bfca
+    | "vdsm-compat", "0.10" -> compat := "0.10"
e9bfca
+    | "vdsm-compat", "1.1" -> compat := "1.1"
e9bfca
+    | "vdsm-compat", v ->
e9bfca
+       error (f_"-o vdsm: unknown vdsm-compat level ‘%s’") v
e9bfca
+    | "vdsm-vm-uuid", v ->
e9bfca
+       if !vm_uuid <> None then
e9bfca
+         error (f_"-o vdsm: -oo vdsm-vm-uuid set twice");
e9bfca
+       vm_uuid := Some v;
e9bfca
+    | "vdsm-ovf-output", v ->
e9bfca
+       if !ovf_output <> None then
e9bfca
+         error (f_"-o vdsm: -oo vdsm-ovf-output set twice");
e9bfca
+       ovf_output := Some v;
e9bfca
+    | "vdsm-ovf-flavour", v ->
e9bfca
+       ovf_flavour := Create_ovf.ovf_flavour_of_string v
e9bfca
+    | "vdsm-image-uuid", v ->
e9bfca
+       List.push_front v image_uuids
e9bfca
+    | "vdsm-vol-uuid", v ->
e9bfca
+       List.push_front v vol_uuids
e9bfca
+    | k, _ ->
e9bfca
+       error (f_"-o vdsm: unknown output option ‘-oo %s’") k
e9bfca
+  ) options;
e9bfca
+
e9bfca
+  let compat = !compat in
e9bfca
+  let image_uuids = List.rev !image_uuids in
e9bfca
+  let vol_uuids = List.rev !vol_uuids in
e9bfca
+  if image_uuids = [] || vol_uuids = [] then
e9bfca
+    error (f_"-o vdsm: either -oo vdsm-vol-uuid or -oo vdsm-vm-uuid was not specified");
e9bfca
+  let vm_uuid =
e9bfca
+    match !vm_uuid with
e9bfca
+    | None ->
e9bfca
+       error (f_"-o vdsm: -oo vdsm-image-uuid was not specified")
e9bfca
+    | Some uuid -> uuid in
e9bfca
+  let ovf_output = Option.default "." !ovf_output in
e9bfca
+  let ovf_flavour = !ovf_flavour in
e9bfca
+
e9bfca
+  { image_uuids; vol_uuids; vm_uuid; ovf_output; compat; ovf_flavour }
e9bfca
+
e9bfca
 class output_vdsm os vdsm_options output_alloc =
e9bfca
 object
e9bfca
   inherit output
e9bfca
 
e9bfca
   method as_options =
e9bfca
-    sprintf "-o vdsm -os %s%s%s --vdsm-vm-uuid %s --vdsm-ovf-output %s%s%s" os
e9bfca
+    sprintf "-o vdsm -os %s%s%s -oo vdsm-vm-uuid=%s -oo vdsm-ovf-output=%s%s%s" os
e9bfca
       (String.concat ""
e9bfca
-         (List.map (sprintf " --vdsm-image-uuid %s") vdsm_options.image_uuids))
e9bfca
+         (List.map (sprintf " -oo vdsm-image-uuid=%s")
e9bfca
+                   vdsm_options.image_uuids))
e9bfca
       (String.concat ""
e9bfca
-         (List.map (sprintf " --vdsm-vol-uuid %s") vdsm_options.vol_uuids))
e9bfca
+         (List.map (sprintf " -oo vdsm-vol-uuid=%s")
e9bfca
+                   vdsm_options.vol_uuids))
e9bfca
       vdsm_options.vm_uuid
e9bfca
       vdsm_options.ovf_output
e9bfca
       (match vdsm_options.compat with
e9bfca
        | "0.10" -> "" (* currently this is the default, so don't print it *)
e9bfca
-       | s -> sprintf " --vdsm-compat=%s" s)
e9bfca
+       | s -> sprintf " -oo vdsm-compat=%s" s)
e9bfca
       (match vdsm_options.ovf_flavour with
e9bfca
-       | Create_ovf.OVirt -> "--vdsm-ovf-flavour=ovf"
e9bfca
+       | Create_ovf.OVirt -> "-oo vdsm-ovf-flavour=ovf"
e9bfca
        (* currently this is the default, so don't print it *)
e9bfca
        | Create_ovf.RHVExportStorageDomain -> "")
e9bfca
 
e9bfca
@@ -84,7 +151,7 @@ object
e9bfca
   method prepare_targets _ targets =
e9bfca
     if List.length vdsm_options.image_uuids <> List.length targets ||
e9bfca
       List.length vdsm_options.vol_uuids <> List.length targets then
e9bfca
-      error (f_"the number of ‘--vdsm-image-uuid’ and ‘--vdsm-vol-uuid’ parameters passed on the command line has to match the number of guest disk images (for this guest: %d)")
e9bfca
+      error (f_"the number of ‘-oo vdsm-image-uuid’ and ‘-oo vdsm-vol-uuid’ parameters passed on the command line has to match the number of guest disk images (for this guest: %d)")
e9bfca
         (List.length targets);
e9bfca
 
e9bfca
     let mp, uuid =
e9bfca
diff --git a/v2v/output_vdsm.mli b/v2v/output_vdsm.mli
e9bfca
index 6ed684638..36f327900 100644
e9bfca
--- a/v2v/output_vdsm.mli
e9bfca
+++ b/v2v/output_vdsm.mli
e9bfca
@@ -18,16 +18,13 @@
e9bfca
 
e9bfca
 (** [-o vdsm] target. *)
e9bfca
 
e9bfca
-type vdsm_options = {
e9bfca
-  image_uuids : string list;          (* --vdsm-image-uuid (multiple) *)
e9bfca
-  vol_uuids : string list;            (* --vdsm-vol-uuid (multiple) *)
e9bfca
-  vm_uuid : string;                   (* --vdsm-vm-uuid *)
e9bfca
-  ovf_output : string;                (* --vdsm-ovf-output *)
e9bfca
-  compat : string;                    (* --vdsm-compat=0.10|1.1 *)
e9bfca
-  ovf_flavour : Create_ovf.ovf_flavour;
e9bfca
-}
e9bfca
+type vdsm_options
e9bfca
 (** Miscellaneous extra command line parameters used by VDSM. *)
e9bfca
 
e9bfca
+val print_output_options : unit -> unit
e9bfca
+val parse_output_options : (string * string) list -> vdsm_options
e9bfca
+(** Print and parse vdsm -oo options. *)
e9bfca
+
e9bfca
 val output_vdsm : string -> vdsm_options -> Types.output_allocation -> Types.output
e9bfca
 (** [output_vdsm os vdsm_options output_alloc] creates and
e9bfca
     returns a new {!Types.output} object specialized for writing
e9bfca
diff --git a/v2v/test-v2v-docs.sh b/v2v/test-v2v-docs.sh
e9bfca
index bb1ddefd7..da98050ee 100755
e9bfca
--- a/v2v/test-v2v-docs.sh
e9bfca
+++ b/v2v/test-v2v-docs.sh
e9bfca
@@ -22,4 +22,34 @@ $TEST_FUNCTIONS
e9bfca
 skip_if_skipped
e9bfca
 
e9bfca
 $top_srcdir/podcheck.pl virt-v2v.pod virt-v2v \
e9bfca
-  --ignore=--debug-overlay,--ic,--if,--in-place,--it,--no-trim,--oa,--oc,--of,--on,--op,--os,--vmtype
e9bfca
+  --ignore=\
e9bfca
+--debug-overlay,\
e9bfca
+--ic,\
e9bfca
+--if,\
e9bfca
+--in-place,\
e9bfca
+--io,\
e9bfca
+--it,\
e9bfca
+--no-trim,\
e9bfca
+--oa,\
e9bfca
+--oc,\
e9bfca
+--of,\
e9bfca
+--on,\
e9bfca
+--oo,\
e9bfca
+--op,\
e9bfca
+--os,\
e9bfca
+--vddk-config,\
e9bfca
+--vddk-cookie,\
e9bfca
+--vddk-libdir,\
e9bfca
+--vddk-nfchostport,\
e9bfca
+--vddk-port,\
e9bfca
+--vddk-snapshot,\
e9bfca
+--vddk-thumbprint,\
e9bfca
+--vddk-transports,\
e9bfca
+--vddk-vimapiver,\
e9bfca
+--vdsm-compat,\
e9bfca
+--vdsm-image-uuid,\
e9bfca
+--vdsm-ovf-flavour,\
e9bfca
+--vdsm-ovf-output,\
e9bfca
+--vdsm-vm-uuid,\
e9bfca
+--vdsm-vol-uuid,\
e9bfca
+--vmtype
e9bfca
diff --git a/v2v/test-v2v-it-vddk-io-query.sh b/v2v/test-v2v-it-vddk-io-query.sh
e9bfca
new file mode 100755
e9bfca
index 000000000..014e30207
e9bfca
--- /dev/null
e9bfca
+++ b/v2v/test-v2v-it-vddk-io-query.sh
e9bfca
@@ -0,0 +1,38 @@
e9bfca
+#!/bin/bash -
e9bfca
+# libguestfs virt-v2v test script
e9bfca
+# Copyright (C) 2018 Red Hat Inc.
e9bfca
+#
e9bfca
+# This program is free software; you can redistribute it and/or modify
e9bfca
+# it under the terms of the GNU General Public License as published by
e9bfca
+# the Free Software Foundation; either version 2 of the License, or
e9bfca
+# (at your option) any later version.
e9bfca
+#
e9bfca
+# This program is distributed in the hope that it will be useful,
e9bfca
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
e9bfca
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
e9bfca
+# GNU General Public License for more details.
e9bfca
+#
e9bfca
+# You should have received a copy of the GNU General Public License
e9bfca
+# along with this program; if not, write to the Free Software
e9bfca
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
e9bfca
+
e9bfca
+# Test -io "?" option.
e9bfca
+
e9bfca
+set -e
e9bfca
+
e9bfca
+$TEST_FUNCTIONS
e9bfca
+skip_if_skipped
e9bfca
+
e9bfca
+export VIRT_TOOLS_DATA_DIR="$top_srcdir/test-data/fake-virt-tools"
e9bfca
+export VIRTIO_WIN="$top_srcdir/test-data/fake-virtio-win"
e9bfca
+
e9bfca
+f=test-v2v-it-vddk-io-query.actual
e9bfca
+rm -f $f
e9bfca
+
e9bfca
+$VG virt-v2v --debug-gc \
e9bfca
+    -it vddk -io "?" > $f
e9bfca
+
e9bfca
+grep -- "-io vddk-config" $f
e9bfca
+grep -- "-io vddk-thumbprint" $f
e9bfca
+
e9bfca
+rm $f
e9bfca
diff --git a/v2v/test-v2v-o-vdsm-oo-query.sh b/v2v/test-v2v-o-vdsm-oo-query.sh
e9bfca
new file mode 100755
e9bfca
index 000000000..5691446ea
e9bfca
--- /dev/null
e9bfca
+++ b/v2v/test-v2v-o-vdsm-oo-query.sh
e9bfca
@@ -0,0 +1,38 @@
e9bfca
+#!/bin/bash -
e9bfca
+# libguestfs virt-v2v test script
e9bfca
+# Copyright (C) 2018 Red Hat Inc.
e9bfca
+#
e9bfca
+# This program is free software; you can redistribute it and/or modify
e9bfca
+# it under the terms of the GNU General Public License as published by
e9bfca
+# the Free Software Foundation; either version 2 of the License, or
e9bfca
+# (at your option) any later version.
e9bfca
+#
e9bfca
+# This program is distributed in the hope that it will be useful,
e9bfca
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
e9bfca
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
e9bfca
+# GNU General Public License for more details.
e9bfca
+#
e9bfca
+# You should have received a copy of the GNU General Public License
e9bfca
+# along with this program; if not, write to the Free Software
e9bfca
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
e9bfca
+
e9bfca
+# Test -oo "?" option.
e9bfca
+
e9bfca
+set -e
e9bfca
+
e9bfca
+$TEST_FUNCTIONS
e9bfca
+skip_if_skipped
e9bfca
+
e9bfca
+export VIRT_TOOLS_DATA_DIR="$top_srcdir/test-data/fake-virt-tools"
e9bfca
+export VIRTIO_WIN="$top_srcdir/test-data/fake-virtio-win"
e9bfca
+
e9bfca
+f=test-v2v-o-vdsm-oo-query.actual
e9bfca
+rm -f $f
e9bfca
+
e9bfca
+$VG virt-v2v --debug-gc \
e9bfca
+    -o vdsm -oo "?" > $f
e9bfca
+
e9bfca
+grep -- "-oo vdsm-compat" $f
e9bfca
+grep -- "-oo vdsm-image-uuid" $f
e9bfca
+
e9bfca
+rm $f
e9bfca
diff --git a/v2v/test-v2v-o-vdsm-options.sh b/v2v/test-v2v-o-vdsm-options.sh
e9bfca
index 4ad5d4aad..65ce1234e 100755
e9bfca
--- a/v2v/test-v2v-o-vdsm-options.sh
e9bfca
+++ b/v2v/test-v2v-o-vdsm-options.sh
e9bfca
@@ -16,7 +16,7 @@
e9bfca
 # along with this program; if not, write to the Free Software
e9bfca
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
e9bfca
 
e9bfca
-# Test -o vdsm options --vdsm-*-uuid
e9bfca
+# Test -o vdsm options -oo vdsm-*-uuid
e9bfca
 
e9bfca
 set -e
e9bfca
 set -x
e9bfca
@@ -44,19 +44,19 @@ mkdir $d/12345678-1234-1234-1234-123456789abc/master
e9bfca
 mkdir $d/12345678-1234-1234-1234-123456789abc/master/vms
e9bfca
 mkdir $d/12345678-1234-1234-1234-123456789abc/master/vms/VM
e9bfca
 
e9bfca
-# The --vdsm-*-uuid options don't actually check that the
e9bfca
+# The -oo vdsm-*-uuid options don't actually check that the
e9bfca
 # parameter is a UUID, which is useful here.
e9bfca
 
e9bfca
 $VG virt-v2v --debug-gc \
e9bfca
     -i libvirt -ic "$libvirt_uri" windows \
e9bfca
     -o vdsm -os $d/12345678-1234-1234-1234-123456789abc \
e9bfca
     -of qcow2 \
e9bfca
-    --vdsm-image-uuid IMAGE \
e9bfca
-    --vdsm-vol-uuid VOL \
e9bfca
-    --vdsm-vm-uuid VM \
e9bfca
-    --vdsm-ovf-output $d/12345678-1234-1234-1234-123456789abc/master/vms/VM \
e9bfca
-    --vdsm-compat=1.1 \
e9bfca
-    --vdsm-ovf-flavour=ovirt
e9bfca
+    -oo vdsm-image-uuid=IMAGE \
e9bfca
+    -oo vdsm-vol-uuid=VOL \
e9bfca
+    -oo vdsm-vm-uuid=VM \
e9bfca
+    -oo vdsm-ovf-output=$d/12345678-1234-1234-1234-123456789abc/master/vms/VM \
e9bfca
+    -oo vdsm-compat=1.1 \
e9bfca
+    -oo vdsm-ovf-flavour=ovirt
e9bfca
 
e9bfca
 # Test the OVF metadata was created.
e9bfca
 test -f $d/12345678-1234-1234-1234-123456789abc/master/vms/VM/VM.ovf
e9bfca
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
e9bfca
index 4df3791a9..5dd888e77 100644
e9bfca
--- a/v2v/virt-v2v.pod
e9bfca
+++ b/v2v/virt-v2v.pod
e9bfca
@@ -273,6 +273,47 @@ For I<-i disk> only, this specifies the format of the input disk
e9bfca
 image.  For other input methods you should specify the input
e9bfca
 format in the metadata.
e9bfca
 
e9bfca
+=item B<-io> OPTION=VALUE
e9bfca
+
e9bfca
+Set input option(s) related to the current input mode or transport.
e9bfca
+To display short help on what options are available you can use:
e9bfca
+
e9bfca
+ virt-v2v -it vddk -io "?"
e9bfca
+
e9bfca
+=item B<-io vddk-libdir=>LIBDIR
e9bfca
+
e9bfca
+Set the VDDK library directory.  This directory should I<contain>
e9bfca
+subdirectories called F<include>, F<lib64> etc., but do not include
e9bfca
+F<lib64> actually in the parameter.
e9bfca
+
e9bfca
+In most cases this parameter is required when using the I<-it vddk>
e9bfca
+(VDDK) transport.  See L</INPUT FROM VDDK> below for details.
e9bfca
+
e9bfca
+=item B<-io vddk-thumbprint=>xx:xx:xx:...
e9bfca
+
e9bfca
+Set the thumbprint of the remote VMware server.
e9bfca
+
e9bfca
+This parameter is required when using the I<-it vddk> (VDDK) transport.
e9bfca
+See L</INPUT FROM VDDK> below for details.
e9bfca
+
e9bfca
+=item B<-io vddk-config=>FILENAME
e9bfca
+
e9bfca
+=item B<-io vddk-cookie=>COOKIE
e9bfca
+
e9bfca
+=item B<-io vddk-nfchostport=>PORT
e9bfca
+
e9bfca
+=item B<-io vddk-port=>PORT
e9bfca
+
e9bfca
+=item B<-io vddk-snapshot=>SNAPSHOT-MOREF
e9bfca
+
e9bfca
+=item B<-io vddk-transports=>MODE:MODE:...
e9bfca
+
e9bfca
+=item B<-io vddk-vimapiver=>APIVER
e9bfca
+
e9bfca
+When using VDDK mode, these options are passed unmodified to the
e9bfca
+L<nbdkit(1)> VDDK plugin.  Please refer to L<nbdkit-vddk-plugin(1)>.
e9bfca
+These are all optional.
e9bfca
+
e9bfca
 =item B<-it> B<ssh>
e9bfca
 
e9bfca
 When using I<-i vmx>, this enables the ssh transport.
e9bfca
@@ -282,7 +323,7 @@ See L</INPUT FROM VMWARE VMX> below.
e9bfca
 
e9bfca
 Use VMware VDDK as a transport to copy the input disks.  See
e9bfca
 L</INPUT FROM VDDK> below.  If you use this parameter then you may
e9bfca
-need to use other I<--vddk*> options to specify how to connect through
e9bfca
+need to use other I<-io vddk*> options to specify how to connect through
e9bfca
 VDDK.
e9bfca
 
e9bfca
 =item B<--keys-from-stdin>
e9bfca
@@ -442,6 +483,95 @@ If not specified, then the input format is used.
e9bfca
 Rename the guest when converting it.  If this option is not used then
e9bfca
 the output name is the same as the input name.
e9bfca
 
e9bfca
+=item B<-oo> OPTION=VALUE
e9bfca
+
e9bfca
+Set output option(s) related to the current output mode.
e9bfca
+To display short help on what options are available you can use:
e9bfca
+
e9bfca
+ virt-v2v -o vdsm -oo "?"
e9bfca
+
e9bfca
+=item B<-oo vdsm-compat=0.10>
e9bfca
+
e9bfca
+=item B<-oo vdsm-compat=1.1>
e9bfca
+
e9bfca
+If I<-o vdsm> and the output format is qcow2, then we add the qcow2
e9bfca
+I<compat=0.10> option to the output file for compatibility with RHEL 6
e9bfca
+(see L<https://bugzilla.redhat.com/1145582>).
e9bfca
+
e9bfca
+If I<-oo vdsm-compat=1.1> is used then modern qcow2 (I<compat=1.1>)
e9bfca
+files are generated instead.
e9bfca
+
e9bfca
+Currently I<-oo vdsm-compat=0.10> is the default, but this will change
e9bfca
+to I<-oo vdsm-compat=1.1> in a future version of virt-v2v (when we can
e9bfca
+assume that everyone is using a modern version of qemu).
e9bfca
+
e9bfca
+B<Note this option only affects I<-o vdsm> output>.  All other output
e9bfca
+modes (including I<-o rhv>) generate modern qcow2 I<compat=1.1>
e9bfca
+files, always.
e9bfca
+
e9bfca
+If this option is available, then C<vdsm-compat-option> will appear in
e9bfca
+the I<--machine-readable> output.
e9bfca
+
e9bfca
+=item B<-oo vdsm-image-uuid=>UUID
e9bfca
+
e9bfca
+=item B<-oo vdsm-vol-uuid=>UUID
e9bfca
+
e9bfca
+=item B<-oo vdsm-vm-uuid=>UUID
e9bfca
+
e9bfca
+=item B<-oo vdsm-ovf-output=>DIR
e9bfca
+
e9bfca
+Normally the RHV output mode chooses random UUIDs for the target
e9bfca
+guest.  However VDSM needs to control the UUIDs and passes these
e9bfca
+parameters when virt-v2v runs under VDSM control.  The parameters
e9bfca
+control:
e9bfca
+
e9bfca
+=over 4
e9bfca
+
e9bfca
+=item *
e9bfca
+
e9bfca
+the image directory of each guest disk (I<-oo vdsm-image-uuid>) (this
e9bfca
+option is passed once for each guest disk)
e9bfca
+
e9bfca
+=item *
e9bfca
+
e9bfca
+UUIDs for each guest disk (I<-oo vdsm-vol-uuid>) (this option
e9bfca
+is passed once for each guest disk)
e9bfca
+
e9bfca
+=item *
e9bfca
+
e9bfca
+the OVF file name (I<-oo vdsm-vm-uuid>).
e9bfca
+
e9bfca
+=item *
e9bfca
+
e9bfca
+the OVF output directory (default current directory) (I<-oo vdsm-ovf-output>).
e9bfca
+
e9bfca
+=back
e9bfca
+
e9bfca
+The format of UUIDs is: C<12345678-1234-1234-1234-123456789abc> (each
e9bfca
+hex digit can be C<0-9> or C<a-f>), conforming to S<OSF DCE 1.1>.
e9bfca
+
e9bfca
+These options can only be used with I<-o vdsm>.
e9bfca
+
e9bfca
+=item B<-oo vdsm-ovf-flavour=>flavour
e9bfca
+
e9bfca
+This option controls the format of the OVF generated at the end of conversion.
e9bfca
+Currently there are two possible flavours:
e9bfca
+
e9bfca
+=over 4
e9bfca
+
e9bfca
+=item rhevexp
e9bfca
+
e9bfca
+The OVF format used in RHV export storage domain.
e9bfca
+
e9bfca
+=item ovirt
e9bfca
+
e9bfca
+The OVF format understood by oVirt REST API.
e9bfca
+
e9bfca
+=back
e9bfca
+
e9bfca
+For backward compatibility the default is I<rhevexp>, but this may change in
e9bfca
+the future.
e9bfca
+
e9bfca
 =item B<-op> file
e9bfca
 
e9bfca
 Supply a file containing a password to be used when connecting to the
e9bfca
@@ -538,122 +668,6 @@ boot an operating system from the first virtio disk.  Specifically,
e9bfca
 F</boot> must be on the first virtio disk, and it cannot chainload an
e9bfca
 OS which is not in the first virtio disk.
e9bfca
 
e9bfca
-=item B<--vddk-libdir> LIBDIR
e9bfca
-
e9bfca
-Set the VDDK library directory.  This directory should I<contain>
e9bfca
-subdirectories called F<include>, F<lib64> etc., but do not include
e9bfca
-F<lib64> actually in the parameter.
e9bfca
-
e9bfca
-In most cases this parameter is required when using the I<-it vddk>
e9bfca
-(VDDK) transport.  See L</INPUT FROM VDDK> below for details.
e9bfca
-
e9bfca
-=item B<--vddk-thumbprint> xx:xx:xx:...
e9bfca
-
e9bfca
-Set the thumbprint of the remote VMware server.
e9bfca
-
e9bfca
-This parameter is required when using the I<-it vddk> (VDDK) transport.
e9bfca
-See L</INPUT FROM VDDK> below for details.
e9bfca
-
e9bfca
-=item B<--vddk-config> FILENAME
e9bfca
-
e9bfca
-=item B<--vddk-cookie> COOKIE
e9bfca
-
e9bfca
-=item B<--vddk-nfchostport> PORT
e9bfca
-
e9bfca
-=item B<--vddk-port> PORT
e9bfca
-
e9bfca
-=item B<--vddk-snapshot> SNAPSHOT-MOREF
e9bfca
-
e9bfca
-=item B<--vddk-transports> MODE:MODE:...
e9bfca
-
e9bfca
-=item B<--vddk-vimapiver> APIVER
e9bfca
-
e9bfca
-When using VDDK mode, these options are passed unmodified to the
e9bfca
-L<nbdkit(1)> VDDK plugin.  Please refer to L<nbdkit-vddk-plugin(1)>.
e9bfca
-These are all optional.
e9bfca
-
e9bfca
-=item B<--vdsm-compat=0.10>
e9bfca
-
e9bfca
-=item B<--vdsm-compat=1.1>
e9bfca
-
e9bfca
-If I<-o vdsm> and the output format is qcow2, then we add the qcow2
e9bfca
-I<compat=0.10> option to the output file for compatibility with RHEL 6
e9bfca
-(see L<https://bugzilla.redhat.com/1145582>).
e9bfca
-
e9bfca
-If I<--vdsm-compat=1.1> is used then modern qcow2 (I<compat=1.1>)
e9bfca
-files are generated instead.
e9bfca
-
e9bfca
-Currently I<--vdsm-compat=0.10> is the default, but this will change
e9bfca
-to I<--vdsm-compat=1.1> in a future version of virt-v2v (when we can
e9bfca
-assume that everyone is using a modern version of qemu).
e9bfca
-
e9bfca
-B<Note this option only affects I<-o vdsm> output>.  All other output
e9bfca
-modes (including I<-o rhv>) generate modern qcow2 I<compat=1.1>
e9bfca
-files, always.
e9bfca
-
e9bfca
-If this option is available, then C<vdsm-compat-option> will appear in
e9bfca
-the I<--machine-readable> output.
e9bfca
-
e9bfca
-=item B<--vdsm-image-uuid> UUID
e9bfca
-
e9bfca
-=item B<--vdsm-vol-uuid> UUID
e9bfca
-
e9bfca
-=item B<--vdsm-vm-uuid> UUID
e9bfca
-
e9bfca
-=item B<--vdsm-ovf-output>
e9bfca
-
e9bfca
-Normally the RHV output mode chooses random UUIDs for the target
e9bfca
-guest.  However VDSM needs to control the UUIDs and passes these
e9bfca
-parameters when virt-v2v runs under VDSM control.  The parameters
e9bfca
-control:
e9bfca
-
e9bfca
-=over 4
e9bfca
-
e9bfca
-=item *
e9bfca
-
e9bfca
-the image directory of each guest disk (I<--vdsm-image-uuid>) (this
e9bfca
-option is passed once for each guest disk)
e9bfca
-
e9bfca
-=item *
e9bfca
-
e9bfca
-UUIDs for each guest disk (I<--vdsm-vol-uuid>) (this option
e9bfca
-is passed once for each guest disk)
e9bfca
-
e9bfca
-=item *
e9bfca
-
e9bfca
-the OVF file name (I<--vdsm-vm-uuid>).
e9bfca
-
e9bfca
-=item *
e9bfca
-
e9bfca
-the OVF output directory (default current directory) (I<--vdsm-ovf-output>).
e9bfca
-
e9bfca
-=back
e9bfca
-
e9bfca
-The format of UUIDs is: C<12345678-1234-1234-1234-123456789abc> (each
e9bfca
-hex digit can be C<0-9> or C<a-f>), conforming to S<OSF DCE 1.1>.
e9bfca
-
e9bfca
-These options can only be used with I<-o vdsm>.
e9bfca
-
e9bfca
-=item B<--vdsm-ovf-flavour> flavour
e9bfca
-
e9bfca
-This option controls the format of the OVF generated at the end of conversion.
e9bfca
-Currently there are two possible flavours:
e9bfca
-
e9bfca
-=over 4
e9bfca
-
e9bfca
-=item rhevexp
e9bfca
-
e9bfca
-The OVF format used in RHV export storage domain.
e9bfca
-
e9bfca
-=item ovirt
e9bfca
-
e9bfca
-The OVF format understood by oVirt REST API.
e9bfca
-
e9bfca
-=back
e9bfca
-
e9bfca
-For backward compatibility the default is I<rhevexp>, but this may change in
e9bfca
-the future.
e9bfca
-
e9bfca
 =item B<-v>
e9bfca
 
e9bfca
 =item B<--verbose>
e9bfca
@@ -1528,15 +1542,15 @@ SSL thumbprint:
e9bfca
  $ virt-v2v \
e9bfca
      -ic 'vpx://root@vcenter.example.com/Datacenter/esxi?no_verify=1' \
e9bfca
      -it vddk \
e9bfca
-     --vddk-libdir /path/to/vmware-vix-disklib-distrib \
e9bfca
-     --vddk-thumbprint xx:xx:xx:... \
e9bfca
+     -io vddk-libdir=/path/to/vmware-vix-disklib-distrib \
e9bfca
+     -io vddk-thumbprint=xx:xx:xx:... \
e9bfca
      "Windows 2003" \
e9bfca
      -o local -os /var/tmp
e9bfca
 
e9bfca
 Other options that you might need to add in rare circumstances include
e9bfca
-I<--vddk-config>, I<--vddk-cookie>, I<--vddk-nfchostport>,
e9bfca
-I<--vddk-port>, I<--vddk-snapshot>, I<--vddk-transports> and
e9bfca
-I<--vddk-vimapiver>, which are all explained in the
e9bfca
+I<-io vddk-config>, I<-io vddk-cookie>, I<-io vddk-nfchostport>,
e9bfca
+I<-io vddk-port>, I<-io vddk-snapshot>, I<-io vddk-transports> and
e9bfca
+I<-io vddk-vimapiver>, which are all explained in the
e9bfca
 L<nbdkit-vddk-plugin(1)> documentation.
e9bfca
 
e9bfca
 =head2 VDDK: DEBUGGING VDDK FAILURES
e9bfca
-- 
3d5c2a
2.17.2
e9bfca