From d8bbc5ce092c42570ece3da1ab720df318c9294e Mon Sep 17 00:00:00 2001 From: Chris Roberts Date: Wed, 7 Nov 2018 15:53:46 -0800 Subject: [PATCH] Add support for specifying the default NIC type used for guest adapters Provides support for defining the NIC type used for any guest adapter which does not define an adapter type. This is defaulted to "virtio". --- .../providers/virtualbox/action/network.rb | 12 +++++- plugins/providers/virtualbox/config.rb | 20 ++++++++++ .../virtualbox/action/network_test.rb | 38 ++++++++++++++++++- .../providers/virtualbox/config_test.rb | 30 ++++++++++++++- .../docs/virtualbox/configuration.html.md | 21 ++++++++++ 5 files changed, 117 insertions(+), 4 deletions(-) diff --git a/plugins/providers/virtualbox/action/network.rb b/plugins/providers/virtualbox/action/network.rb index af9e0a5c7..8f8e163c1 100644 --- a/plugins/providers/virtualbox/action/network.rb +++ b/plugins/providers/virtualbox/action/network.rb @@ -37,6 +37,8 @@ module VagrantPlugins available_slots.delete(slot) end + default_nic_type = env[:machine].provider_config.default_nic_type + @logger.debug("Available slots for high-level adapters: #{available_slots.inspect}") @logger.info("Determining network adapters required for high-level configuration...") available_slots = available_slots.to_a.sort @@ -44,6 +46,11 @@ module VagrantPlugins # We only handle private and public networks next if type != :private_network && type != :public_network + if default_nic_type && !options.key?(:nic_type) && !options.key?(:virtualbox__nic_type) + @logger.info("Setting default nic type (`#{default_nic_type}`) for `#{type}` - `#{options}`") + options[:virtualbox__nic_type] = default_nic_type + end + options = scoped_hash_override(options, :virtualbox) # Figure out the slot that this adapter will go into @@ -403,15 +410,16 @@ module VagrantPlugins end def nat_config(options) - return { + return options.merge( auto_config: false - } + ) end def nat_adapter(config) return { adapter: config[:adapter], type: :nat, + nic_type: config[:nic_type], } end diff --git a/plugins/providers/virtualbox/config.rb b/plugins/providers/virtualbox/config.rb index d549606ec..f64b208d6 100644 --- a/plugins/providers/virtualbox/config.rb +++ b/plugins/providers/virtualbox/config.rb @@ -19,6 +19,13 @@ module VagrantPlugins # @return [Array] attr_reader :customizations + # Set the default type of NIC hardware to be used for network + # devices. By default this is "virtio". If it is set to `nil` + # no type will be set and VirtualBox's default will be used. + # + # @return [String] + attr_accessor :default_nic_type + # If true, unused network interfaces will automatically be deleted. # This defaults to false because the detection does not work across # multiple users, and because on Windows this operation requires @@ -68,6 +75,7 @@ module VagrantPlugins @auto_nat_dns_proxy = UNSET_VALUE @check_guest_additions = UNSET_VALUE @customizations = [] + @default_nic_type = UNSET_VALUE @destroy_unused_network_interfaces = UNSET_VALUE @functional_vboxsf = UNSET_VALUE @name = UNSET_VALUE @@ -158,6 +166,9 @@ module VagrantPlugins # The default name is just nothing, and we default it @name = nil if @name == UNSET_VALUE + + @default_nic_type = "virtio" if @default_nic_type == UNSET_VALUE + set_default_nic_type! if @default_nic_type end def validate(machine) @@ -190,6 +201,15 @@ module VagrantPlugins { "VirtualBox Provider" => errors } end + def set_default_nic_type! + network_adapters.each do |_, args| + _, opts = args + if opts && !opts.key?(:nic_type) + opts[:nic_type] = @default_nic_type + end + end + end + def to_s "VirtualBox" end diff --git a/test/unit/plugins/providers/virtualbox/action/network_test.rb b/test/unit/plugins/providers/virtualbox/action/network_test.rb index 34ed17d94..1e6bc7c88 100644 --- a/test/unit/plugins/providers/virtualbox/action/network_test.rb +++ b/test/unit/plugins/providers/virtualbox/action/network_test.rb @@ -84,6 +84,42 @@ describe VagrantPlugins::ProviderVirtualBox::Action::Network do expect{ subject.call(env) }.not_to raise_error(Vagrant::Errors::NetworkAddressInvalid) end + describe "setting nic type" do + before do + guest = double("guest") + allow(driver).to receive(:read_bridged_interfaces) { [] } + allow(driver).to receive(:read_host_only_interfaces) { [] } + allow(driver).to receive(:create_host_only_network) { {} } + allow(driver).to receive(:read_dhcp_servers) { [] } + allow(driver).to receive(:create_dhcp_server) + allow(machine).to receive(:guest) { guest } + allow(guest).to receive(:capability) + end + + it "sets default nic type when unset" do + machine.config.vm.network 'private_network', { type: 'dhcp' } + subject.call(env) + _, net_config = machine.config.vm.networks.detect { |type, _| type == :private_network } + expect(net_config[:virtualbox__nic_type]).to eq("virtio") + end + + it "does not set nic type when already set" do + machine.config.vm.network 'private_network', { type: 'dhcp', nic_type: "custom" } + subject.call(env) + _, net_config = machine.config.vm.networks.detect { |type, _| type == :private_network } + expect(net_config[:nic_type]).to eq("custom") + expect(net_config[:virtualbox__nic_type]).to be_nil + end + + it "does not set nic type when namespaced option is set" do + machine.config.vm.network 'private_network', { type: 'dhcp', virtualbox__nic_type: "custom" } + subject.call(env) + _, net_config = machine.config.vm.networks.detect { |type, _| type == :private_network } + expect(net_config[:nic_type]).to be_nil + expect(net_config[:virtualbox__nic_type]).to eq("custom") + end + end + context "with a dhcp private network" do let(:bridgedifs) { [] } let(:hostonlyifs) { [] } @@ -118,7 +154,7 @@ describe VagrantPlugins::ProviderVirtualBox::Action::Network do mac: nil, name: nil, netmask: "255.255.255.0", - nic_type: nil, + nic_type: "virtio", type: :dhcp, dhcp_ip: "172.28.128.2", dhcp_lower: "172.28.128.3", diff --git a/test/unit/plugins/providers/virtualbox/config_test.rb b/test/unit/plugins/providers/virtualbox/config_test.rb index 1b125cb42..1355c4e9b 100644 --- a/test/unit/plugins/providers/virtualbox/config_test.rb +++ b/test/unit/plugins/providers/virtualbox/config_test.rb @@ -43,14 +43,42 @@ describe VagrantPlugins::ProviderVirtualBox::Config do it { expect(subject.gui).to be(false) } it { expect(subject.name).to be_nil } it { expect(subject.functional_vboxsf).to be(true) } + it { expect(subject.default_nic_type).to eq("virtio") } it "should have one NAT adapter" do expect(subject.network_adapters).to eql({ - 1 => [:nat, {}], + 1 => [:nat, {nic_type: "virtio"}], }) end end + describe "#default_nic_type" do + let(:nic_type) { "custom" } + + before do + subject.default_nic_type = nic_type + subject.finalize! + end + + it { expect(subject.default_nic_type).to eq(nic_type) } + + it "should set NAT adapter nic type" do + expect(subject.network_adapters.values.first.last[:nic_type]). + to eq(nic_type) + end + + context "when set to nil" do + let(:nic_type) { nil } + + it { expect(subject.default_nic_type).to be_nil } + + it "should not set NAT adapter nic type" do + expect(subject.network_adapters.values.first.last[:nic_type]). + to be_nil + end + end + end + describe "#merge" do let(:one) { described_class.new } let(:two) { described_class.new } diff --git a/website/source/docs/virtualbox/configuration.html.md b/website/source/docs/virtualbox/configuration.html.md index a2d27d68f..a4aaf9a3b 100644 --- a/website/source/docs/virtualbox/configuration.html.md +++ b/website/source/docs/virtualbox/configuration.html.md @@ -41,6 +41,27 @@ config.vm.provider "virtualbox" do |v| end ``` +## Default NIC Type + +By default Vagrant will set the NIC type for all network interfaces to +`"virtio"`. If you would rather a different NIC type be used as the +default for guests: + +```ruby +config.vm.provider "virtualbox" do |v| + v.default_nic_type = "82543GC" +end +``` + +or if you would like to disable the default type so VirtualBox's default +is applied you can set the value to `nil`: + +```ruby +config.vm.provider "virtualbox" do |v| + v.default_nic_type = nil +end +``` + ## Linked Clones By default new machines are created by importing the base box. For large