Skip to content

Commit f509231

Browse files
committed
Add ipv4_only option to limit connecting to guest IPv4 addresses only
1 parent 3d68e16 commit f509231

File tree

5 files changed

+69
-4
lines changed

5 files changed

+69
-4
lines changed

plugins/providers/hyperv/action/wait_for_ip_address.rb

+6-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ def initialize(app, env)
1212

1313
def call(env)
1414
timeout = env[:machine].provider_config.ip_address_timeout
15+
ipv4_only = env[:machine].provider_config.ipv4_only
1516

1617
env[:ui].output("Waiting for the machine to report its IP address...")
1718
env[:ui].detail("Timeout: #{timeout} seconds")
19+
if ipv4_only
20+
env[:ui].detail("Waiting for IPv4 address only")
21+
end
1822

1923
guest_ip = nil
2024
Timeout.timeout(timeout) do
@@ -29,8 +33,8 @@ def call(env)
2933

3034
if guest_ip
3135
begin
32-
IPAddr.new(guest_ip)
33-
break
36+
ip = IPAddr.new(guest_ip)
37+
break unless ipv4_only && !ip.ipv4?()
3438
rescue IPAddr::InvalidAddressError
3539
# Ignore, continue looking.
3640
@logger.warn("Invalid IP address returned: #{guest_ip}")

plugins/providers/hyperv/config.rb

+7
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class Config < Vagrant.plugin("2", :config)
5050
attr_accessor :vm_integration_services
5151
# @return [Boolean] Enable Enhanced session mode
5252
attr_accessor :enable_enhanced_session_mode
53+
# @return [Boolean] Enable IPv4 only for connection to guest
54+
attr_accessor :ipv4_only
5355

5456
def initialize
5557
@ip_address_timeout = UNSET_VALUE
@@ -68,6 +70,7 @@ def initialize
6870
@enable_checkpoints = UNSET_VALUE
6971
@vm_integration_services = {}
7072
@enable_enhanced_session_mode = UNSET_VALUE
73+
@ipv4_only = UNSET_VALUE
7174
end
7275

7376
def finalize!
@@ -107,6 +110,10 @@ def finalize!
107110
@enable_checkpoints ||= @enable_automatic_checkpoints
108111

109112
@enable_enhanced_session_mode = false if @enable_enhanced_session_mode == UNSET_VALUE
113+
114+
if @ipv4_only == UNSET_VALUE
115+
@ipv4_only = Vagrant::Util::Platform.wsl? ? true : false
116+
end
110117
end
111118

112119
def validate(machine)

test/unit/plugins/providers/hyperv/action/wait_for_ip_address_test.rb

+29-1
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@
99
let(:provider){ double("provider", driver: driver) }
1010
let(:driver){ double("driver") }
1111
let(:machine){ double("machine", provider: provider, provider_config: provider_config) }
12-
let(:provider_config){ double("provider_config", ip_address_timeout: ip_address_timeout) }
12+
let(:provider_config){ double("provider_config", ip_address_timeout: ip_address_timeout, ipv4_only: ipv4_only) }
1313
let(:ip_address_timeout){ 1 }
14+
let(:ipv4_only){ false }
1415

1516
let(:subject){ described_class.new(app, env) }
1617

1718
before do
1819
allow(driver).to receive(:read_guest_ip).and_return("ip" => "127.0.0.1")
1920
allow(app).to receive(:call)
21+
allow(Vagrant::Util::Platform).to receive(:wsl?).and_return(false)
2022
end
2123

2224
it "should call the app on success" do
@@ -35,4 +37,30 @@
3537
expect(subject).to receive(:sleep)
3638
subject.call(env)
3739
end
40+
41+
it "should call the app on success with IPv6 address" do
42+
expect(driver).to receive(:read_guest_ip).and_return("ip" => "FE80:0000:0000:0000:0202:B3FF:FE1E:8329")
43+
subject.call(env)
44+
end
45+
46+
context "IPv4_only" do
47+
let(:ipv4_only){ true }
48+
49+
it "should call the app on success" do
50+
expect(app).to receive(:call)
51+
subject.call(env)
52+
end
53+
54+
it "should set a timeout for waiting for IPv4 address" do
55+
expect(Timeout).to receive(:timeout).with(ip_address_timeout)
56+
subject.call(env)
57+
end
58+
59+
it "should retry until it receives a valid IPv4 address" do
60+
expect(driver).to receive(:read_guest_ip).and_return("ip" => "FE80:0000:0000:0000:0202:B3FF:FE1E:8329")
61+
expect(driver).to receive(:read_guest_ip).and_return("ip" => "127.0.0.1")
62+
expect(subject).to receive(:sleep)
63+
subject.call(env)
64+
end
65+
end
3866
end

test/unit/plugins/providers/hyperv/config_test.rb

+26-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,6 @@
242242
end
243243
end
244244

245-
246245
describe "#enable_enhanced_session_mode" do
247246
it "is false by default" do
248247
subject.finalize!
@@ -255,4 +254,30 @@
255254
expect(subject.enable_enhanced_session_mode).to eq(true)
256255
end
257256
end
257+
258+
describe "#ipv4_only" do
259+
context "within the WSL" do
260+
before{ allow(Vagrant::Util::Platform).to receive(:wsl?).and_return(true) }
261+
262+
it "is true by default when in WSL" do
263+
subject.finalize!
264+
expect(subject.ipv4_only).to eq(true)
265+
end
266+
end
267+
268+
context "not within the WSL" do
269+
before{ allow(Vagrant::Util::Platform).to receive(:wsl?).and_return(false) }
270+
271+
it "is false by default" do
272+
subject.finalize!
273+
expect(subject.ipv4_only).to eq(false)
274+
end
275+
end
276+
277+
it "can be set" do
278+
subject.ipv4_only = true
279+
subject.finalize!
280+
expect(subject.ipv4_only).to eq(true)
281+
end
282+
end
258283
end

website/content/docs/providers/hyperv/configuration.mdx

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ you may set. A complete reference is shown below:
2020
- `enable_automatic_checkpoints` (boolean) Enable automatic checkpoints of the VM. Default: false
2121
- `enable_enhanced_session_mode` (boolean) - Enable enhanced session transport type for the VM. Default: false
2222
- `ip_address_timeout` (integer) - Number of seconds to wait for the VM to report an IP address. Default: 120.
23+
- `ipv4_only` (boolean) - Only connect to a guests IPv4 address ignoring an IPv6 address. Default: false unless running in WSL, in which case it will default to true.
2324
- `linked_clone` (boolean) - Use differencing disk instead of cloning entire VHD. Default: false
2425
- `mac` (string) - MAC address for the guest network interface
2526
- `maxmemory` (integer) - Maximum number of megabytes allowed to be allocated for the VM. When set Dynamic Memory Allocation will be enabled.

0 commit comments

Comments
 (0)