mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
v2v: Add --network and --bridge options to perform network name mapping.
This commit is contained in:
6
v2v/TODO
6
v2v/TODO
@@ -9,6 +9,7 @@ Missing features compared to Perl version:
|
||||
p2v:
|
||||
|
||||
- network dialog and network configuration
|
||||
- network mapping
|
||||
- control where the image is sent (ie. RHEV ESD, libvirt, etc)
|
||||
|
||||
p2v/conversion.c: "/tmp/virt-p2v-%04d%02d%02d-XXXXXXXX",
|
||||
@@ -26,11 +27,6 @@ v2v/source_libvirt.ml: * XXX Quoting, although it's not needed for v
|
||||
v2v/target_RHEV.ml: (* Old virt-v2v ignored removable media. XXX *)
|
||||
v2v/types.mli: (* Only used by RHEV. XXX Should be parameterized type. *)
|
||||
|
||||
Perform network mapping on command line, eg:
|
||||
--network net1 # Means map "default" to "net1"
|
||||
--network net:net2 # Means map "net" to "net2"
|
||||
How did old virt-v2v do this?
|
||||
|
||||
For OVA support we need to have the source write to the final target
|
||||
directory (where possible as it might not always be possible to do
|
||||
that). One way to do this is to have an early target hook, called
|
||||
|
||||
@@ -57,6 +57,19 @@ let parse_cmdline () =
|
||||
error (f_"unknown -i option: %s") s
|
||||
in
|
||||
|
||||
let network_map = ref [] in
|
||||
let add_network, add_bridge =
|
||||
let add 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
|
||||
in
|
||||
let add_network str = add Network str
|
||||
and add_bridge str = add Bridge str in
|
||||
add_network, add_bridge
|
||||
in
|
||||
|
||||
let output_mode = ref `Libvirt in
|
||||
let set_output_mode = function
|
||||
| "libvirt" -> output_mode := `Libvirt
|
||||
@@ -89,6 +102,7 @@ let parse_cmdline () =
|
||||
|
||||
let ditto = " -\"-" in
|
||||
let argspec = Arg.align [
|
||||
"--bridge", Arg.String add_bridge, "in:out " ^ s_"Map bridge 'in' to 'out'";
|
||||
"--debug-gc",Arg.Set debug_gc, " " ^ s_"Debug GC and memory allocations";
|
||||
"-i", Arg.String set_input_mode, "disk|libvirt|libvirtxml " ^ s_"Set input mode (default: libvirt)";
|
||||
"-ic", Arg.Set_string input_conn, "uri " ^ s_"Libvirt URI";
|
||||
@@ -96,6 +110,7 @@ let parse_cmdline () =
|
||||
"format " ^ s_"Input format (for -i disk)";
|
||||
"--long-options", Arg.Unit display_long_options, " " ^ s_"List long options";
|
||||
"--machine-readable", Arg.Set machine_readable, " " ^ s_"Make output machine readable";
|
||||
"--network", Arg.String add_network, "in:out " ^ s_"Map network 'in' to 'out'";
|
||||
"--no-copy", Arg.Clear do_copy, " " ^ s_"Just write the metadata";
|
||||
"-o", Arg.String set_output_mode, "libvirt|local|rhev " ^ s_"Set output mode (default: libvirt)";
|
||||
"-oa", Arg.String set_output_alloc, "sparse|preallocated " ^ s_"Set output allocation mode";
|
||||
@@ -152,6 +167,7 @@ read the man page virt-v2v(1).
|
||||
let input_format = match !input_format with "" -> None | s -> Some s in
|
||||
let input_mode = !input_mode in
|
||||
let machine_readable = !machine_readable in
|
||||
let network_map = !network_map in
|
||||
let output_alloc = !output_alloc in
|
||||
let output_conn = match !output_conn with "" -> None | s -> Some s in
|
||||
let output_format = match !output_format with "" -> None | s -> Some s in
|
||||
@@ -248,5 +264,6 @@ read the man page virt-v2v(1).
|
||||
OutputRHEV (output_storage, rhev_params) in
|
||||
|
||||
input, output,
|
||||
debug_gc, do_copy, output_alloc, output_format, output_name,
|
||||
debug_gc, do_copy, network_map,
|
||||
output_alloc, output_format, output_name,
|
||||
quiet, root_choice, trace, verbose
|
||||
|
||||
@@ -60,7 +60,7 @@ let create input_format disk =
|
||||
let network = {
|
||||
s_mac = None;
|
||||
s_vnet = "default";
|
||||
s_vnet_type = `Network
|
||||
s_vnet_type = Network
|
||||
} in
|
||||
|
||||
let source = {
|
||||
@@ -73,7 +73,7 @@ let create input_format disk =
|
||||
s_display = None;
|
||||
s_disks = [disk];
|
||||
s_removables = [];
|
||||
s_nics = [ network ];
|
||||
s_nics = [network];
|
||||
} in
|
||||
|
||||
source
|
||||
|
||||
@@ -209,8 +209,8 @@ let create_xml ?(map_source_file = identity) ?(map_source_dev = identity) xml =
|
||||
|
||||
let vnet_type =
|
||||
match xpath_to_string "@type" "" with
|
||||
| "network" -> Some `Network
|
||||
| "bridge" -> Some `Bridge
|
||||
| "network" -> Some Network
|
||||
| "bridge" -> Some Bridge
|
||||
| _ -> None in
|
||||
match vnet_type with
|
||||
| None -> ()
|
||||
|
||||
@@ -114,7 +114,7 @@ let create_libvirt_xml ?pool source overlays guestcaps =
|
||||
fun { s_mac = mac; s_vnet_type = vnet_type; s_vnet = vnet } ->
|
||||
let vnet_type_str =
|
||||
match vnet_type with
|
||||
| `Bridge -> "bridge" | `Network -> "network" in
|
||||
| Bridge -> "bridge" | Network -> "network" in
|
||||
|
||||
let nic =
|
||||
e "interface" [ "type", vnet_type_str ] [
|
||||
|
||||
@@ -82,8 +82,9 @@ and source_removable = {
|
||||
and source_nic = {
|
||||
s_mac : string option;
|
||||
s_vnet : string;
|
||||
s_vnet_type : [`Bridge|`Network];
|
||||
s_vnet_type : vnet_type;
|
||||
}
|
||||
and vnet_type = Bridge | Network
|
||||
and source_display = {
|
||||
s_display_type : [`VNC|`Spice];
|
||||
s_keymap : string option;
|
||||
@@ -137,7 +138,7 @@ and string_of_source_removable { s_removable_type = typ;
|
||||
|
||||
and string_of_source_nic { s_mac = mac; s_vnet = vnet; s_vnet_type = typ } =
|
||||
sprintf "%s%s%s"
|
||||
(match typ with `Bridge -> "bridge" | `Network -> "network")
|
||||
(match typ with Bridge -> "bridge" | Network -> "network")
|
||||
vnet
|
||||
(match mac with
|
||||
| None -> ""
|
||||
|
||||
@@ -74,9 +74,10 @@ and source_removable = {
|
||||
and source_nic = {
|
||||
s_mac : string option; (** MAC address. *)
|
||||
s_vnet : string; (** Source network name. *)
|
||||
s_vnet_type : [`Bridge|`Network]; (** Source network type. *)
|
||||
s_vnet_type : vnet_type; (** Source network type. *)
|
||||
}
|
||||
(** Network interfaces. *)
|
||||
and vnet_type = Bridge | Network
|
||||
|
||||
and source_display = {
|
||||
s_display_type : [`VNC|`Spice]; (** Display type. *)
|
||||
|
||||
25
v2v/v2v.ml
25
v2v/v2v.ml
@@ -32,7 +32,8 @@ let () = Random.self_init ()
|
||||
let rec main () =
|
||||
(* Handle the command line. *)
|
||||
let input, output,
|
||||
debug_gc, do_copy, output_alloc, output_format, output_name,
|
||||
debug_gc, do_copy, network_map,
|
||||
output_alloc, output_format, output_name,
|
||||
quiet, root_choice, trace, verbose =
|
||||
Cmdline.parse_cmdline () in
|
||||
|
||||
@@ -58,6 +59,28 @@ let rec main () =
|
||||
*)
|
||||
| Some name -> { source with s_name = name } in
|
||||
|
||||
(* Map networks and bridges. *)
|
||||
let source =
|
||||
let { s_nics = nics } = source in
|
||||
let nics = List.map (
|
||||
fun ({ s_vnet_type = t; s_vnet = vnet } as nic) ->
|
||||
try
|
||||
(* Look for a --network or --bridge parameter which names this
|
||||
* network/bridge (eg. --network in:out).
|
||||
*)
|
||||
let new_name = List.assoc (t, vnet) 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, "") network_map in
|
||||
{ nic with s_vnet = new_name }
|
||||
with Not_found ->
|
||||
(* Not found, so return the original NIC unchanged. *)
|
||||
nic
|
||||
) nics in
|
||||
{ source with s_nics = nics } in
|
||||
|
||||
(* Create a qcow2 v3 overlay to protect the source image(s). There
|
||||
* is a specific reason to use the newer qcow2 variant: Because the
|
||||
* L2 table can store zero clusters efficiently, and because
|
||||
|
||||
@@ -7,7 +7,7 @@ virt-v2v - Convert a guest to use KVM
|
||||
virt-v2v -ic esx://esx.example.com/ esx_guest
|
||||
|
||||
virt-v2v -ic esx://esx.example.com/ \
|
||||
-o rhev -os rhev.nfs:/export_domain esx_guest
|
||||
-o rhev -os rhev.nfs:/export_domain --network rhevm esx_guest
|
||||
|
||||
virt-v2v -i libvirtxml -o local -os /tmp guest-domain.xml
|
||||
|
||||
@@ -80,10 +80,11 @@ This is the same as the previous example, except you want to send the
|
||||
guest to a RHEV-M Export Storage Domain which is located remotely
|
||||
(over NFS) at C<rhev.nfs:/export_domain>. If you are unclear about
|
||||
the location of the Export Storage Domain you should check the
|
||||
settings on your RHEV-M management console.
|
||||
settings on your RHEV-M management console. Guest network
|
||||
interface(s) are connected to the target network called C<rhevm>.
|
||||
|
||||
virt-v2v -ic esx://esx.example.com/ \
|
||||
-o rhev -os rhev.nfs:/export_domain esx_guest
|
||||
-o rhev -os rhev.nfs:/export_domain --network rhevm esx_guest
|
||||
|
||||
In this case the host running virt-v2v acts as a B<conversion server>.
|
||||
|
||||
@@ -120,6 +121,10 @@ command line.
|
||||
|
||||
Display help.
|
||||
|
||||
=item B<--bridge> ...
|
||||
|
||||
See I<--network> below.
|
||||
|
||||
=item B<--debug-gc>
|
||||
|
||||
Debug garbage collection and memory allocation. This is only useful
|
||||
@@ -176,6 +181,18 @@ This option is used to make the output more machine friendly
|
||||
when being parsed by other programs. See
|
||||
L</MACHINE READABLE OUTPUT> below.
|
||||
|
||||
=item B<--network> in:out
|
||||
|
||||
=item B<--network> out
|
||||
|
||||
=item B<--bridge> in:out
|
||||
|
||||
=item B<--bridge> out
|
||||
|
||||
Map network (or bridge) called C<in> to network (or bridge) called
|
||||
C<out>. If no C<in:> prefix is given, all other networks (or bridges)
|
||||
are mapped to C<out>.
|
||||
|
||||
=item B<--no-copy>
|
||||
|
||||
Don't copy the disks. Instead, conversion is performed (and thrown
|
||||
|
||||
Reference in New Issue
Block a user