---
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