-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allows Hyper-V driver to select IP address based on preferred protocol #23
base: master
Are you sure you want to change the base?
Changes from 2 commits
cfb21a3
e5b2079
d3b4e7c
d615d62
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ package hyperv | |
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"net" | ||
"os" | ||
|
@@ -16,16 +17,23 @@ import ( | |
"github.com/docker/machine/libmachine/state" | ||
) | ||
|
||
const ( | ||
DefaultProtocol = iota | ||
PreferIPv4 | ||
PreferIPv6 | ||
) | ||
|
||
type Driver struct { | ||
*drivers.BaseDriver | ||
Boot2DockerURL string | ||
VSwitch string | ||
DiskSize int | ||
MemSize int | ||
CPU int | ||
MacAddr string | ||
VLanID int | ||
DisableDynamicMemory bool | ||
Boot2DockerURL string | ||
VSwitch string | ||
DiskSize int | ||
MemSize int | ||
CPU int | ||
MacAddr string | ||
VLanID int | ||
DisableDynamicMemory bool | ||
PreferredNetworkProtocol int | ||
} | ||
|
||
const ( | ||
|
@@ -35,6 +43,7 @@ const ( | |
defaultVLanID = 0 | ||
defaultDisableDynamicMemory = false | ||
defaultSwitchID = "c08cb7b8-9b3c-408e-8e30-5e16a3aeb444" | ||
defaultTimeout = time.Minute * 10 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. awfully long time out... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How long do you think it's appropriate? 3 or 5 min? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a default of 3 is long enough, since when more is needed, the caller should override this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. |
||
) | ||
|
||
// NewDriver creates a new Hyper-v driver with default settings. | ||
|
@@ -99,6 +108,11 @@ func (d *Driver) GetCreateFlags() []mcnflag.Flag { | |
Usage: "Disable dynamic memory management setting", | ||
EnvVar: "HYPERV_DISABLE_DYNAMIC_MEMORY", | ||
}, | ||
mcnflag.IntFlag{ | ||
Name: "hyperv-preferred-network-protocol", | ||
Usage: "Preferred network protocol (IPv4/v6)", | ||
EnvVar: "HYPERV_PREFERRED_NETWORK_PROTOCOL", | ||
}, | ||
} | ||
} | ||
|
||
|
@@ -328,12 +342,17 @@ func (d *Driver) chooseVirtualSwitch() (string, error) { | |
func (d *Driver) waitForIP() (string, error) { | ||
log.Infof("Waiting for host to start...") | ||
|
||
start := time.Now() | ||
for { | ||
ip, _ := d.GetIP() | ||
if ip != "" { | ||
return ip, nil | ||
} | ||
|
||
if time.Since(start) >= defaultTimeout { | ||
return "", errors.New("timeout waiting for IP") | ||
} | ||
|
||
time.Sleep(1 * time.Second) | ||
} | ||
} | ||
|
@@ -342,6 +361,7 @@ func (d *Driver) waitForIP() (string, error) { | |
func (d *Driver) waitStopped() error { | ||
log.Infof("Waiting for host to stop...") | ||
|
||
start := time.Now() | ||
for { | ||
s, err := d.GetState() | ||
if err != nil { | ||
|
@@ -352,6 +372,10 @@ func (d *Driver) waitStopped() error { | |
return nil | ||
} | ||
|
||
if time.Since(start) >= defaultTimeout { | ||
return errors.New("timeout waiting for stopped") | ||
} | ||
|
||
time.Sleep(1 * time.Second) | ||
} | ||
} | ||
|
@@ -428,6 +452,10 @@ func (d *Driver) Kill() error { | |
return nil | ||
} | ||
|
||
func isIPv4(address string) bool { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What we do in Minishift is as follows: https://github.com/minishift/minishift/blob/0efa5d527d77a7651eac75a4861097ab4a203f43/cmd/minishift/cmd/start_preflight.go#L485-L491
should be enough and relies on the framework instead of counting delimiters.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought about using
I'm not sure which format could be accepted by minikube (either converting it back to IPv4 or still using this IPv6 format). Therefore, I used delimiter counting instead of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was not sure which format v4 or v6 should be returned in this case as the function asks for a string. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't seem IPv4 address in IPv6 format functions well on Windows. |
||
return strings.Count(address, ":") < 2 | ||
} | ||
|
||
func (d *Driver) GetIP() (string, error) { | ||
s, err := d.GetState() | ||
if err != nil { | ||
|
@@ -437,7 +465,7 @@ func (d *Driver) GetIP() (string, error) { | |
return "", drivers.ErrHostIsNotRunning | ||
} | ||
|
||
stdout, err := cmdOut("((", "Hyper-V\\Get-VM", d.MachineName, ").networkadapters[0]).ipaddresses[0]") | ||
stdout, err := cmdOut("((", "Hyper-V\\Get-VM", d.MachineName, ").networkadapters[0]).ipaddresses") | ||
if err != nil { | ||
return "", err | ||
} | ||
|
@@ -447,7 +475,33 @@ func (d *Driver) GetIP() (string, error) { | |
return "", fmt.Errorf("IP not found") | ||
} | ||
|
||
return resp[0], nil | ||
switch d.PreferredNetworkProtocol { | ||
case PreferIPv4: | ||
for _, ipStr := range resp { | ||
ip := net.ParseIP(ipStr) | ||
if isIPv4(ipStr) && ip.To4() != nil && ip.IsGlobalUnicast() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See previous comment... it would make this check easier as no To4 is needed, as we already know this. |
||
return ipStr, nil | ||
} | ||
} | ||
|
||
case PreferIPv6: | ||
for _, ipStr := range resp { | ||
ip := net.ParseIP(ipStr) | ||
if !isIPv4(ipStr) && ip.IsGlobalUnicast() { | ||
return ipStr, nil | ||
} | ||
} | ||
|
||
default: | ||
for _, ipStr := range resp { | ||
ip := net.ParseIP(ipStr) | ||
if ip.IsGlobalUnicast() { | ||
return ipStr, nil | ||
} | ||
} | ||
} | ||
|
||
return "", nil | ||
} | ||
|
||
func (d *Driver) publicSSHKeyPath() string { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which is? this is not clear... as what defines the default ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would depend on the adapter and DHCP setting.
I believe it's the reason why sometimes an IPv6 address gets returned by the driver and fails minikube.
Do you have any better naming for this option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it also happens with the Defautl Switch, while this should always AFAIK return a valid IPv4 addres... but this is not the case. In case of failures in thenetworking stack we have seen IPv6 being returned as a link-local.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not say protocol, but just Default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good.