Blame SOURCES/0231-v2v-Error-if-certain-options-appear-twice-on-the-com.patch

ffd6ed
From dfe4588a80857523cdc3f6426dd22f766442aec1 Mon Sep 17 00:00:00 2001
ffd6ed
From: "Richard W.M. Jones" <rjones@redhat.com>
ffd6ed
Date: Mon, 7 Sep 2015 12:10:09 +0100
ffd6ed
Subject: [PATCH] v2v: Error if certain options appear twice on the command
ffd6ed
 line.
ffd6ed
ffd6ed
Change the handling of -ic, -if, -oc, -of, -on, -os, --password-file,
ffd6ed
--vdsm-vm-uuid, --vdsm-ovf-output, --vmtype options, so that if any
ffd6ed
appear multiple times on the command line we error out:
ffd6ed
ffd6ed
$ virt-v2v -i disk /tmp/centos-6.img -o null -of qcow2 -of raw
ffd6ed
virt-v2v: error: -of option used more than once on the command line
ffd6ed
ffd6ed
Thanks: Juquin Zhou for finding the bug.
ffd6ed
(cherry picked from commit e27199274645dad962670bb75f87cc7472d36c4d)
ffd6ed
---
ffd6ed
 v2v/cmdline.ml | 150 ++++++++++++++++++++++++++++++++++-----------------------
ffd6ed
 1 file changed, 91 insertions(+), 59 deletions(-)
ffd6ed
ffd6ed
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
ffd6ed
index 97167b4..30155a5 100644
ffd6ed
--- a/v2v/cmdline.ml
ffd6ed
+++ b/v2v/cmdline.ml
ffd6ed
@@ -35,22 +35,30 @@ let parse_cmdline () =
ffd6ed
   let debug_gc = ref false in
ffd6ed
   let debug_overlays = ref false in
ffd6ed
   let do_copy = ref true in
ffd6ed
-  let input_conn = ref "" in
ffd6ed
-  let input_format = ref "" in
ffd6ed
   let machine_readable = ref false in
ffd6ed
-  let output_conn = ref "" in
ffd6ed
-  let output_format = ref "" in
ffd6ed
-  let output_name = ref "" in
ffd6ed
-  let output_storage = ref "" in
ffd6ed
-  let password_file = ref "" in
ffd6ed
   let print_source = ref false in
ffd6ed
   let qemu_boot = ref false in
ffd6ed
   let quiet = ref false in
ffd6ed
-  let vdsm_vm_uuid = ref "" in
ffd6ed
-  let vdsm_ovf_output = ref "." in
ffd6ed
   let verbose = ref false in
ffd6ed
   let trace = ref false in
ffd6ed
-  let vmtype = ref "" in
ffd6ed
+
ffd6ed
+  let input_conn = ref None in
ffd6ed
+  let input_format = ref None in
ffd6ed
+  let output_conn = ref None in
ffd6ed
+  let output_format = ref None in
ffd6ed
+  let output_name = ref None in
ffd6ed
+  let output_storage = ref None in
ffd6ed
+  let password_file = ref None in
ffd6ed
+  let vdsm_vm_uuid = ref None in
ffd6ed
+  let vdsm_ovf_output = ref None in (* default "." *)
ffd6ed
+  let vmtype = ref None in
ffd6ed
+  let set_string_option_once optname optref arg =
ffd6ed
+    match !optref with
ffd6ed
+    | Some _ ->
ffd6ed
+       error (f_"%s option used more than once on the command line") optname
ffd6ed
+    | None ->
ffd6ed
+       optref := Some arg
ffd6ed
+  in
ffd6ed
 
ffd6ed
   let input_mode = ref `Not_set in
ffd6ed
   let set_input_mode mode =
ffd6ed
@@ -152,9 +160,10 @@ let parse_cmdline () =
ffd6ed
     "--debug-overlays",Arg.Set debug_overlays,
ffd6ed
     ditto;
ffd6ed
     "-i",        Arg.String set_input_mode, i_options ^ " " ^ s_"Set input mode (default: libvirt)";
ffd6ed
-    "-ic",       Arg.Set_string input_conn, "uri " ^ s_"Libvirt URI";
ffd6ed
-    "-if",       Arg.Set_string input_format,
ffd6ed
-    "format " ^ s_"Input format (for -i disk)";
ffd6ed
+    "-ic",       Arg.String (set_string_option_once "-ic" input_conn),
ffd6ed
+                                            "uri " ^ s_"Libvirt URI";
ffd6ed
+    "-if",       Arg.String (set_string_option_once "-if" input_format),
ffd6ed
+                                            "format " ^ s_"Input format (for -i disk)";
ffd6ed
     "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options";
ffd6ed
     "--machine-readable", Arg.Set machine_readable, " " ^ s_"Make output machine readable";
ffd6ed
     "-n",        Arg.String add_network,    "in:out " ^ s_"Map network 'in' to 'out'";
ffd6ed
@@ -162,30 +171,35 @@ let parse_cmdline () =
ffd6ed
     "--no-copy", Arg.Clear do_copy,         " " ^ s_"Just write the metadata";
ffd6ed
     "--no-trim", Arg.String set_no_trim,    "all|mp,mp,.." ^ " " ^ s_"Don't trim selected mounts";
ffd6ed
     "-o",        Arg.String set_output_mode, o_options ^ " " ^ s_"Set output mode (default: libvirt)";
ffd6ed
-    "-oa",       Arg.String set_output_alloc, "sparse|preallocated " ^ s_"Set output allocation mode";
ffd6ed
-    "-oc",       Arg.Set_string output_conn, "uri " ^ s_"Libvirt URI";
ffd6ed
-    "-of",       Arg.Set_string output_format, "raw|qcow2 " ^ s_"Set output format";
ffd6ed
-    "-on",       Arg.Set_string output_name, "name " ^ s_"Rename guest when converting";
ffd6ed
-    "-os",       Arg.Set_string output_storage, "storage " ^ s_"Set output storage location";
ffd6ed
-    "--password-file", Arg.Set_string password_file, "file " ^ s_"Use password from file";
ffd6ed
+    "-oa",       Arg.String set_output_alloc,
ffd6ed
+                                            "sparse|preallocated " ^ s_"Set output allocation mode";
ffd6ed
+    "-oc",       Arg.String (set_string_option_once "-oc" output_conn),
ffd6ed
+                                            "uri " ^ s_"Libvirt URI";
ffd6ed
+    "-of",       Arg.String (set_string_option_once "-of" output_format),
ffd6ed
+                                            "raw|qcow2 " ^ s_"Set output format";
ffd6ed
+    "-on",       Arg.String (set_string_option_once "-on" output_name),
ffd6ed
+                                            "name " ^ s_"Rename guest when converting";
ffd6ed
+    "-os",       Arg.String (set_string_option_once "-os" output_storage),
ffd6ed
+                                            "storage " ^ s_"Set output storage location";
ffd6ed
+    "--password-file", Arg.String (set_string_option_once "--password-file" password_file),
ffd6ed
+                                            "file " ^ s_"Use password from file";
ffd6ed
     "--print-source", Arg.Set print_source, " " ^ s_"Print source and stop";
ffd6ed
     "--qemu-boot", Arg.Set qemu_boot,       " " ^ s_"This option cannot be used in RHEL";
ffd6ed
     "-q",        Arg.Set quiet,             " " ^ s_"Quiet output";
ffd6ed
     "--quiet",   Arg.Set quiet,             ditto;
ffd6ed
     "--root",    Arg.String set_root_choice,"ask|... " ^ s_"How to choose root filesystem";
ffd6ed
-    "--vdsm-image-uuid",
ffd6ed
-    Arg.String add_vdsm_image_uuid, "uuid " ^ s_"Output image UUID(s)";
ffd6ed
-    "--vdsm-vol-uuid",
ffd6ed
-    Arg.String add_vdsm_vol_uuid, "uuid " ^ s_"Output vol UUID(s)";
ffd6ed
-    "--vdsm-vm-uuid",
ffd6ed
-    Arg.Set_string vdsm_vm_uuid, "uuid " ^ s_"Output VM UUID";
ffd6ed
-    "--vdsm-ovf-output",
ffd6ed
-    Arg.Set_string vdsm_ovf_output, " " ^ s_"Output OVF file";
ffd6ed
+    "--vdsm-image-uuid", Arg.String add_vdsm_image_uuid, "uuid " ^ s_"Output image UUID(s)";
ffd6ed
+    "--vdsm-vol-uuid", Arg.String add_vdsm_vol_uuid, "uuid " ^ s_"Output vol UUID(s)";
ffd6ed
+    "--vdsm-vm-uuid", Arg.String (set_string_option_once "--vdsm-vm-uuid" vdsm_vm_uuid),
ffd6ed
+                                            "uuid " ^ s_"Output VM UUID";
ffd6ed
+    "--vdsm-ovf-output", Arg.String (set_string_option_once "--vdsm-ovf-output" vdsm_ovf_output),
ffd6ed
+                                            " " ^ s_"Output OVF file";
ffd6ed
     "-v",        Arg.Set verbose,           " " ^ s_"Enable debugging messages";
ffd6ed
     "--verbose", Arg.Set verbose,           ditto;
ffd6ed
     "-V",        Arg.Unit display_version,  " " ^ s_"Display version and exit";
ffd6ed
     "--version", Arg.Unit display_version,  ditto;
ffd6ed
-    "--vmtype",  Arg.Set_string vmtype,     "server|desktop " ^ s_"Set vmtype (for RHEV)";
ffd6ed
+    "--vmtype",  Arg.String (set_string_option_once "--vmtype" vmtype),
ffd6ed
+                                            "server|desktop " ^ s_"Set vmtype (for RHEV)";
ffd6ed
     "-x",        Arg.Set trace,             " " ^ s_"Enable tracing of libguestfs calls";
ffd6ed
   ] in
ffd6ed
   long_options := argspec;
ffd6ed
@@ -220,19 +234,19 @@ read the man page virt-v2v(1).
ffd6ed
   let debug_gc = !debug_gc in
ffd6ed
   let debug_overlays = !debug_overlays in
ffd6ed
   let do_copy = !do_copy in
ffd6ed
-  let input_conn = match !input_conn with "" -> None | s -> Some s in
ffd6ed
-  let input_format = match !input_format with "" -> None | s -> Some s in
ffd6ed
+  let input_conn = !input_conn in
ffd6ed
+  let input_format = !input_format in
ffd6ed
   let input_mode = !input_mode in
ffd6ed
   let machine_readable = !machine_readable in
ffd6ed
   let network_map = !network_map in
ffd6ed
   let no_trim = !no_trim in
ffd6ed
   let output_alloc = !output_alloc in
ffd6ed
-  let output_conn = match !output_conn with "" -> None | s -> Some s in
ffd6ed
-  let output_format = match !output_format with "" -> None | s -> Some s in
ffd6ed
+  let output_conn = !output_conn in
ffd6ed
+  let output_format = !output_format in
ffd6ed
   let output_mode = !output_mode in
ffd6ed
-  let output_name = match !output_name with "" -> None | s -> Some s in
ffd6ed
+  let output_name = !output_name in
ffd6ed
   let output_storage = !output_storage in
ffd6ed
-  let password_file = match !password_file with "" -> None | s -> Some s in
ffd6ed
+  let password_file = !password_file in
ffd6ed
   let print_source = !print_source in
ffd6ed
   let qemu_boot = !qemu_boot in
ffd6ed
   let quiet = !quiet in
ffd6ed
@@ -240,14 +254,15 @@ read the man page virt-v2v(1).
ffd6ed
   let vdsm_image_uuids = List.rev !vdsm_image_uuids in
ffd6ed
   let vdsm_vol_uuids = List.rev !vdsm_vol_uuids in
ffd6ed
   let vdsm_vm_uuid = !vdsm_vm_uuid in
ffd6ed
-  let vdsm_ovf_output = !vdsm_ovf_output in
ffd6ed
+  let vdsm_ovf_output =
ffd6ed
+    match !vdsm_ovf_output with None -> "." | Some s -> s in
ffd6ed
   let verbose = !verbose in
ffd6ed
   let trace = !trace in
ffd6ed
   let vmtype =
ffd6ed
     match !vmtype with
ffd6ed
-    | "server" -> Some `Server
ffd6ed
-    | "desktop" -> Some `Desktop
ffd6ed
-    | "" -> None
ffd6ed
+    | Some "server" -> Some `Server
ffd6ed
+    | Some "desktop" -> Some `Desktop
ffd6ed
+    | None -> None
ffd6ed
     | _ ->
ffd6ed
       error (f_"unknown --vmtype option, must be \"server\" or \"desktop\"") in
ffd6ed
 
ffd6ed
@@ -319,7 +334,7 @@ read the man page virt-v2v(1).
ffd6ed
     | `Glance ->
ffd6ed
       if output_conn <> None then
ffd6ed
         error (f_"-o glance: -oc option cannot be used in this output mode");
ffd6ed
-      if output_storage <> "" then
ffd6ed
+      if output_storage <> None then
ffd6ed
         error (f_"-o glance: -os option cannot be used in this output mode");
ffd6ed
       if qemu_boot then
ffd6ed
         error (f_"-o glance: --qemu-boot option cannot be used in this output mode");
ffd6ed
@@ -332,7 +347,7 @@ read the man page virt-v2v(1).
ffd6ed
     | `Not_set
ffd6ed
     | `Libvirt ->
ffd6ed
       let output_storage =
ffd6ed
-        if output_storage = "" then "default" else output_storage in
ffd6ed
+        match output_storage with None -> "default" | Some os -> os in
ffd6ed
       if qemu_boot then
ffd6ed
         error (f_"-o libvirt: --qemu-boot option cannot be used in this output mode");
ffd6ed
       if vmtype <> None then
ffd6ed
@@ -342,21 +357,23 @@ read the man page virt-v2v(1).
ffd6ed
       Output_libvirt.output_libvirt verbose output_conn output_storage
ffd6ed
 
ffd6ed
     | `Local ->
ffd6ed
-      if output_storage = "" then
ffd6ed
-        error (f_"-o local: output directory was not specified, use '-os /dir'");
ffd6ed
-      if not (is_directory output_storage) then
ffd6ed
-        error (f_"-os %s: output directory does not exist or is not a directory")
ffd6ed
-          output_storage;
ffd6ed
+      let os =
ffd6ed
+        match output_storage with
ffd6ed
+        | None ->
ffd6ed
+           error (f_"-o local: output directory was not specified, use '-os /dir'")
ffd6ed
+        | Some d when not (is_directory d) ->
ffd6ed
+           error (f_"-os %s: output directory does not exist or is not a directory") d
ffd6ed
+        | Some d -> d in
ffd6ed
       if qemu_boot then
ffd6ed
         error (f_"-o local: --qemu-boot option cannot be used in this output mode");
ffd6ed
       if vmtype <> None then
ffd6ed
         error (f_"--vmtype option cannot be used with '-o local'");
ffd6ed
-      Output_local.output_local verbose output_storage
ffd6ed
+      Output_local.output_local verbose os
ffd6ed
 
ffd6ed
     | `Null ->
ffd6ed
       if output_conn <> None then
ffd6ed
         error (f_"-o null: -oc option cannot be used in this output mode");
ffd6ed
-      if output_storage <> "" then
ffd6ed
+      if output_storage <> None then
ffd6ed
         error (f_"-o null: -os option cannot be used in this output mode");
ffd6ed
       if qemu_boot then
ffd6ed
         error (f_"-o null: --qemu-boot option cannot be used in this output mode");
ffd6ed
@@ -365,34 +382,49 @@ read the man page virt-v2v(1).
ffd6ed
       Output_null.output_null verbose
ffd6ed
 
ffd6ed
     | `QEmu ->
ffd6ed
-      if not (is_directory output_storage) then
ffd6ed
-        error (f_"-os %s: output directory does not exist or is not a directory")
ffd6ed
-          output_storage;
ffd6ed
       if qemu_boot then
ffd6ed
         error (f_"-o qemu: the --qemu-boot option cannot be used in RHEL");
ffd6ed
-      Output_qemu.output_qemu verbose output_storage qemu_boot
ffd6ed
+      let os =
ffd6ed
+        match output_storage with
ffd6ed
+        | None ->
ffd6ed
+           error (f_"-o qemu: output directory was not specified, use '-os /dir'")
ffd6ed
+        | Some d when not (is_directory d) ->
ffd6ed
+           error (f_"-os %s: output directory does not exist or is not a directory") d
ffd6ed
+        | Some d -> d in
ffd6ed
+      Output_qemu.output_qemu verbose os qemu_boot
ffd6ed
 
ffd6ed
     | `RHEV ->
ffd6ed
-      if output_storage = "" then
ffd6ed
-        error (f_"-o rhev: output storage was not specified, use '-os'");
ffd6ed
+      let os =
ffd6ed
+        match output_storage with
ffd6ed
+        | None ->
ffd6ed
+           error (f_"-o rhev: output storage was not specified, use '-os'");
ffd6ed
+        | Some d -> d in
ffd6ed
       if qemu_boot then
ffd6ed
         error (f_"-o rhev: --qemu-boot option cannot be used in this output mode");
ffd6ed
-      Output_rhev.output_rhev verbose output_storage vmtype output_alloc
ffd6ed
+      Output_rhev.output_rhev verbose os vmtype output_alloc
ffd6ed
 
ffd6ed
     | `VDSM ->
ffd6ed
-      if output_storage = "" then
ffd6ed
-        error (f_"-o vdsm: output storage was not specified, use '-os'");
ffd6ed
+      let os =
ffd6ed
+        match output_storage with
ffd6ed
+        | None ->
ffd6ed
+           error (f_"-o vdsm: output storage was not specified, use '-os'");
ffd6ed
+        | Some d -> d in
ffd6ed
       if qemu_boot then
ffd6ed
         error (f_"-o vdsm: --qemu-boot option cannot be used in this output mode");
ffd6ed
-      if vdsm_image_uuids = [] || vdsm_vol_uuids = [] || vdsm_vm_uuid = "" then
ffd6ed
-        error (f_"-o vdsm: either --vdsm-image-uuid, --vdsm-vol-uuid or --vdsm-vm-uuid was not specified");
ffd6ed
+      let vdsm_vm_uuid =
ffd6ed
+        match vdsm_vm_uuid with
ffd6ed
+        | None ->
ffd6ed
+           error (f_"-o vdsm: --vdsm-image-uuid was not specified")
ffd6ed
+        | Some s -> s in
ffd6ed
+      if vdsm_image_uuids = [] || vdsm_vol_uuids = [] then
ffd6ed
+        error (f_"-o vdsm: either --vdsm-vol-uuid or --vdsm-vm-uuid was not specified");
ffd6ed
       let vdsm_params = {
ffd6ed
         Output_vdsm.image_uuids = vdsm_image_uuids;
ffd6ed
         vol_uuids = vdsm_vol_uuids;
ffd6ed
         vm_uuid = vdsm_vm_uuid;
ffd6ed
         ovf_output = vdsm_ovf_output;
ffd6ed
       } in
ffd6ed
-      Output_vdsm.output_vdsm verbose output_storage vdsm_params
ffd6ed
+      Output_vdsm.output_vdsm verbose os vdsm_params
ffd6ed
         vmtype output_alloc in
ffd6ed
 
ffd6ed
   input, output,
ffd6ed
-- 
ffd6ed
1.8.3.1
ffd6ed