diff --git a/README.md b/README.md index e04d35c..7a15724 100644 --- a/README.md +++ b/README.md @@ -213,7 +213,11 @@ Vagrant.configure("2") do |config| ## Networks Networking features in the form of `config.vm.network` support private networks -concept. +concept. It supports both the virtual network switch routing types and the point to +point Guest OS to Guest OS setting using TCP tunnel interfaces. + +http://wiki.libvirt.org/page/VirtualNetworking +https://libvirt.org/formatdomain.html#elementsNICSTCP Public Network interfaces are currently implemented using the macvtap driver. The macvtap driver is only available with the Linux Kernel version >= 2.6.24. See the following libvirt @@ -221,14 +225,33 @@ documentation for the details of the macvtap usage. http://www.libvirt.org/formatdomain.html#elementsNICSDirect + An examples of network interface definitions: ```ruby - # Private network + # Private network using virtual network switching config.vm.define :test_vm1 do |test_vm1| test_vm1.vm.network :private_network, :ip => "10.20.30.40" end + # Private network. Point to Point between 2 Guest OS using a TCP tunnel + # Guest 1 + config.vm.define :test_vm1 do |test_vm1| + test_vm1.vm.network :private_network, + :libvirt__tcp_tunnel_type => 'server', + # default is 127.0.0.1 if omitted + # :libvirt__tcp_tunnel_ip => '127.0.0.1', + :libvirt__tcp_tunnel_port => '11111' + + # Guest 2 + config.vm.define :test_vm2 do |test_vm2| + test_vm2.vm.network :private_network, + :libvirt__tcp_tunnel_type => 'client', + # default is 127.0.0.1 if omitted + # :libvirt__tcp_tunnel_ip => '127.0.0.1', + :libvirt__tcp_tunnel_port => '11111' + + # Public Network config.vm.define :test_vm1 do |test_vm1| test_vm1.vm.network :public_network, @@ -290,9 +313,19 @@ starts with 'libvirt__' string. Here is a list of those options: * `:libvirt__forward_device` - Name of interface/device, where network should be forwarded (NATed or routed). Used only when creating new network. By default, all physical interfaces are used. +* `:libvirt_tcp_tunnel_type` - Set it to "server" or "client" to enable TCP + tunnel interface configuration. This configuration type uses TCP tunnels to + generate point to point connections between Guests. Useful for Switch VMs like + Cumulus Linux. No virtual switch setting like "libvirt__network_name" applies with TCP + tunnel interfaces and will be ignored if configured. +* `:libvirt_tcp_tunnel_ip` - Sets the source IP of the TCP Tunnel interface. By + default this is `127.0.0.1` +* `:libvirt_tcp_tunnel_port` - Sets the TCP Tunnel interface port that either + the client will connect to, or the server will listen on. * `:mac` - MAC address for the interface. * `:model_type` - parameter specifies the model of the network adapter when you create a domain value by default virtio KVM believe possible values, see the documentation for libvirt + When the option `:libvirt__dhcp_enabled` is to to 'false' it shouldn't matter whether the virtual network contains a DHCP server or not and vagrant-libvirt should not fail on it. The only situation where vagrant-libvirt should fail diff --git a/lib/vagrant-libvirt/action/create_network_interfaces.rb b/lib/vagrant-libvirt/action/create_network_interfaces.rb index cbe7562..bd9df2a 100644 --- a/lib/vagrant-libvirt/action/create_network_interfaces.rb +++ b/lib/vagrant-libvirt/action/create_network_interfaces.rb @@ -36,7 +36,6 @@ module VagrantPlugins adapters = [] # Vagrant gives you adapter 0 by default - # Assign interfaces to slots. configured_networks(env, @logger).each do |options| @@ -70,7 +69,6 @@ module VagrantPlugins @mac = iface_configuration.fetch(:mac, false) @model_type = iface_configuration.fetch(:model_type, @nic_model_type) template_name = 'interface' - # Configuration for public interfaces which use the macvtap driver if iface_configuration[:iface_type] == :public_network @device = iface_configuration.fetch(:dev, 'eth0') @@ -80,8 +78,18 @@ module VagrantPlugins template_name = 'public_interface' @logger.info("Setting up public interface using device #{@device} in mode #{@mode}") @ovs = iface_configuration.fetch(:ovs, false) + # configuration for tcp tunnel interfaces (p2p conn btwn guest OSes) + elsif iface_configuration.fetch(:tcp_tunnel_type, nil) + @tcp_tunnel_port = iface_configuration.fetch(:tcp_tunnel_port, nil) + raise Errors::TcpTunnelPortNotDefined if @tcp_tunnel_port.nil? + @tcp_tunnel_ip = iface_configuration.fetch(:tcp_tunnel_address, '127.0.0.1') + @type = iface_configuration.fetch(:tcp_tunnel_type) + @model_type = iface_configuration.fetch(:model_type, @nic_model_type) + template_name = 'tcp_tunnel_interface' + @logger.info("Setting up #{@type} tunnel interface using #{@tcp_tunnel_ip} port #{@tcp_tunnel_port}") end + message = "Creating network interface eth#{@iface_number}" message << " connected to network #{@network_name}." if @mac @@ -144,6 +152,9 @@ module VagrantPlugins network[:type] = :dhcp end + # do not run configure_networks for tcp tunnel interfaces + next if options.fetch(:tcp_tunnel_type, nil) + networks_to_configure << network end @@ -163,6 +174,9 @@ module VagrantPlugins # Return network name according to interface options. def interface_network(libvirt_client, options) + # no need to get interface network for tcp tunnel config + return 'tcp_tunnel' if options.fetch(:tcp_tunnel_type, nil) + if options[:network_name] @logger.debug "Found network by name" return options[:network_name] diff --git a/lib/vagrant-libvirt/action/create_networks.rb b/lib/vagrant-libvirt/action/create_networks.rb index a0d4e54..883c83f 100644 --- a/lib/vagrant-libvirt/action/create_networks.rb +++ b/lib/vagrant-libvirt/action/create_networks.rb @@ -35,7 +35,8 @@ module VagrantPlugins # available, create it if possible. Otherwise raise an error. configured_networks(env, @logger).each do |options| # Only need to create private networks - next if options[:iface_type] != :private_network + next if options[:iface_type] != :private_network or + options.fetch(:tcp_tunnel_type, nil) @logger.debug "Searching for network with options #{options}" # should fix other methods so this doesn't have to be instance var diff --git a/lib/vagrant-libvirt/errors.rb b/lib/vagrant-libvirt/errors.rb index 870c647..863a4f0 100644 --- a/lib/vagrant-libvirt/errors.rb +++ b/lib/vagrant-libvirt/errors.rb @@ -106,6 +106,10 @@ module VagrantPlugins error_key(:activate_network_error) end + class TcpTunnelPortNotDefined < VagrantLibvirtError + error_key(:tcp_tunnel_port_not_defined) + end + # Other exceptions class InterfaceSlotNotAvailable < VagrantLibvirtError error_key(:interface_slot_not_available) diff --git a/lib/vagrant-libvirt/templates/tcp_tunnel_interface.xml.erb b/lib/vagrant-libvirt/templates/tcp_tunnel_interface.xml.erb new file mode 100644 index 0000000..379b740 --- /dev/null +++ b/lib/vagrant-libvirt/templates/tcp_tunnel_interface.xml.erb @@ -0,0 +1,7 @@ + + <% if @mac %> + + <% end %> + + + diff --git a/locales/en.yml b/locales/en.yml index 0644cfc..1ab8e78 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -135,6 +135,8 @@ en: Error while removing network %{network_name}. %{error_message}. delete_snapshot_error: |- Error while deleting snapshot: %{error_message}. + tcp_tunnel_port_not_defined: |- + TCP tunnel port not defined. states: short_paused: |-