[Libguestfs] [PATCH] v2v: Reject duplicate -b/-n parameters on the command line (RHBZ#1325825).

Richard W.M. Jones rjones at redhat.com
Mon Apr 11 13:05:45 UTC 2016


---
 v2v/Makefile.am                          |  3 +-
 v2v/cmdline.ml                           | 31 ++++++++++++++------
 v2v/cmdline.mli                          | 16 ++++++++++-
 v2v/test-v2v-bad-networks-and-bridges.sh | 49 ++++++++++++++++++++++++++++++++
 v2v/v2v.ml                               |  4 +--
 5 files changed, 91 insertions(+), 12 deletions(-)
 create mode 100755 v2v/test-v2v-bad-networks-and-bridges.sh

diff --git a/v2v/Makefile.am b/v2v/Makefile.am
index 4b77ba2..18c2007 100644
--- a/v2v/Makefile.am
+++ b/v2v/Makefile.am
@@ -291,7 +291,8 @@ TESTS = \
 	test-v2v-i-ova-formats.sh \
 	test-v2v-i-ova-gz.sh \
 	test-v2v-i-ova-two-disks.sh \
-	test-v2v-copy-to-local.sh
+	test-v2v-copy-to-local.sh \
+	test-v2v-bad-networks-and-bridges.sh
 
 if HAVE_OCAML_PKG_OUNIT
 TESTS += v2v_unit_tests
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
index 35d18b6..befd8a0 100644
--- a/v2v/cmdline.ml
+++ b/v2v/cmdline.ml
@@ -26,12 +26,18 @@ open Common_utils
 open Types
 open Utils
 
+module NetTypeAndName = struct
+  type t = Types.vnet_type * string option
+  let compare = Pervasives.compare
+end
+module NetworkMap = Map.Make (NetTypeAndName)
+
 type cmdline = {
   compressed : bool;
   debug_overlays : bool;
   do_copy : bool;
   in_place : bool;
-  network_map : ((vnet_type * string) * string) list;
+  network_map : string NetworkMap.t;
   no_trim : string list;
   output_alloc : output_allocation;
   output_format : string option;
@@ -81,16 +87,25 @@ let parse_cmdline () =
       error (f_"unknown -i option: %s") s
   in
 
-  let network_map = ref [] in
+  let network_map = ref NetworkMap.empty in
   let add_network, add_bridge =
-    let add t str =
+    let add flag name t str =
       match String.split ":" str with
-      | "", "" -> error (f_"invalid --bridge or --network parameter")
-      | out, "" | "", out -> network_map := ((t, ""), out) :: !network_map
-      | in_, out -> network_map := ((t, in_), out) :: !network_map
+      | "", "" ->
+         error (f_"invalid %s parameter") flag
+      | out, "" | "", out ->
+         let key = t, None in
+         if NetworkMap.mem key !network_map then
+           error (f_"duplicate %s parameter.  Only one default mapping is allowed.") flag;
+         network_map := NetworkMap.add key out !network_map
+      | in_, out ->
+         let key = t, Some in_ in
+         if NetworkMap.mem key !network_map then
+           error (f_"duplicate %s parameter.  Duplicate mappings specified for %s '%s'.") flag name in_;
+         network_map := NetworkMap.add key out !network_map
     in
-    let add_network str = add Network str
-    and add_bridge str = add Bridge str in
+    let add_network str = add "-n/--network" (s_"network") Network str
+    and add_bridge str = add "-b/--bridge" (s_"bridge") Bridge str in
     add_network, add_bridge
   in
 
diff --git a/v2v/cmdline.mli b/v2v/cmdline.mli
index 8a37686..5d5b39c 100644
--- a/v2v/cmdline.mli
+++ b/v2v/cmdline.mli
@@ -18,12 +18,26 @@
 
 (** Command line argument parsing. *)
 
+module NetTypeAndName : sig
+  type t = Types.vnet_type * string option
+  (** To find the mapping for a specific named network or bridge, use
+      the key [(Network|Bridge, Some name)].  To find the default mapping
+      use [(Network|Bridge, None)]. *)
+  val compare : t -> t -> int
+end
+module NetworkMap : sig
+  type key = NetTypeAndName.t
+  type 'a t = 'a Map.Make(NetTypeAndName).t
+  val mem : key -> 'a t -> bool
+  val find : key -> 'a t -> 'a
+end
+
 type cmdline = {
   compressed : bool;
   debug_overlays : bool;
   do_copy : bool;
   in_place : bool;
-  network_map : ((Types.vnet_type * string) * string) list;
+  network_map : string NetworkMap.t;
   no_trim : string list;
   output_alloc : Types.output_allocation;
   output_format : string option;
diff --git a/v2v/test-v2v-bad-networks-and-bridges.sh b/v2v/test-v2v-bad-networks-and-bridges.sh
new file mode 100755
index 0000000..f336620
--- /dev/null
+++ b/v2v/test-v2v-bad-networks-and-bridges.sh
@@ -0,0 +1,49 @@
+#!/bin/bash -
+# libguestfs virt-v2v test script
+# Copyright (C) 2016 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.
+
+# Test detection of duplicate --network and --bridge parameters.
+
+unset CDPATH
+export LANG=C
+set -e
+set -x
+
+if [ -n "$SKIP_TEST_V2V_BAD_NETWORKS_AND_BRIDGES_SH" ]; then
+    echo "$0: test skipped because environment variable is set"
+    exit 77
+fi
+
+# We expect all of these to print an error.  NB LANG=C above.
+
+virt-v2v -i disk -b b1 -b b1 |& grep "duplicate -b"
+virt-v2v -i disk -n n1 -n n1 |& grep "duplicate -n"
+virt-v2v -i disk -b b1 -n b1 -b b1 |& grep "duplicate -b"
+virt-v2v -i disk -b b1 -n b1 -n b2 |& grep "duplicate -n"
+
+virt-v2v -i disk -b b1:r1 -b b1:r2 |& grep "duplicate -b"
+virt-v2v -i disk -n n1:r1 -n n1:r2 |& grep "duplicate -n"
+
+# The -b and -n parameters are OK in these tests, but because we
+# didn't specify a disk image name on the command line it will give
+# a different error.
+
+virt-v2v -i disk |& grep "expecting a disk image"
+virt-v2v -i disk -b b1 |& grep "expecting a disk image"
+virt-v2v -i disk -n n1 |& grep "expecting a disk image"
+virt-v2v -i disk -b b1 -n n1 |& grep "expecting a disk image"
+virt-v2v -i disk -b b1:r1 -b b2 -n n1:r1 -n n2 |& grep "expecting a disk image"
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index f0c118e..4d0d525 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -189,12 +189,12 @@ and amend_source cmdline source =
         (* Look for a --network or --bridge parameter which names this
          * network/bridge (eg. --network in:out).
          *)
-        let new_name = List.assoc (t, vnet) cmdline.network_map in
+        let new_name = NetworkMap.find (t, Some vnet) cmdline.network_map in
         { nic with s_vnet = new_name }
       with Not_found ->
         try
           (* Not found, so look for a default mapping (eg. --network out). *)
-          let new_name = List.assoc (t, "") cmdline.network_map in
+          let new_name = NetworkMap.find (t, None) cmdline.network_map in
           { nic with s_vnet = new_name }
         with Not_found ->
           (* Not found, so return the original NIC unchanged. *)
-- 
2.7.4




More information about the Libguestfs mailing list