mirror of https://github.com/docker/docs.git
Determine host-only interface dynamically, stop assuming eth1
Signed-off-by: Travis Thieman <travis.thieman@gmail.com>
This commit is contained in:
parent
8046e13683
commit
b57c4c203f
|
@ -652,6 +652,67 @@ func (d *Driver) GetState() (state.State, error) {
|
|||
return state.None, nil
|
||||
}
|
||||
|
||||
func (d *Driver) getHostOnlyMACAddress() (string, error) {
|
||||
// Return the MAC address of the host-only adapter
|
||||
// assigned to this machine. The returned address
|
||||
// is lower-cased and does not contain colons.
|
||||
|
||||
stdout, stderr, err := d.vbmOutErr("showvminfo", d.MachineName, "--machinereadable")
|
||||
if err != nil {
|
||||
if reMachineNotFound.FindString(stderr) != "" {
|
||||
return "", ErrMachineNotExist
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
// First, we get the number of the host-only interface
|
||||
re := regexp.MustCompile(`(?m)^hostonlyadapter([\d]+)`)
|
||||
groups := re.FindStringSubmatch(stdout)
|
||||
if len(groups) < 2 {
|
||||
return "", errors.New("Machine does not have a host-only adapter")
|
||||
}
|
||||
|
||||
// Then we grab the MAC address based on that number
|
||||
adapterNumber := groups[1]
|
||||
re = regexp.MustCompile(fmt.Sprintf("(?m)^macaddress%s=\"(.*)\"", adapterNumber))
|
||||
groups = re.FindStringSubmatch(stdout)
|
||||
if len(groups) < 2 {
|
||||
return "", fmt.Errorf("Could not find MAC address for adapter %v", adapterNumber)
|
||||
}
|
||||
|
||||
return strings.ToLower(groups[1]), nil
|
||||
}
|
||||
|
||||
func (d *Driver) parseIPForMACFromIPAddr(ipAddrOutput string, macAddress string) (string, error) {
|
||||
// Given the output of "ip addr show" on the VM, return the IPv4 address
|
||||
// of the interface with the given MAC address.
|
||||
|
||||
lines := strings.Split(ipAddrOutput, "\n")
|
||||
returnNextIP := false
|
||||
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
if strings.HasPrefix(line, "link") { // line contains MAC address
|
||||
vals := strings.Split(line, " ")
|
||||
if len(vals) >= 2 {
|
||||
macBlock := vals[1]
|
||||
macWithoutColons := strings.Replace(macBlock, ":", "", -1)
|
||||
if macWithoutColons == macAddress { // we are in the correct device block
|
||||
returnNextIP = true
|
||||
}
|
||||
}
|
||||
} else if strings.HasPrefix(line, "inet") && !strings.HasPrefix(line, "inet6") && returnNextIP {
|
||||
vals := strings.Split(line, " ")
|
||||
if len(vals) >= 2 {
|
||||
return vals[1][:strings.Index(vals[1], "/")], nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Could not find matching IP for MAC address %v", macAddress)
|
||||
}
|
||||
|
||||
func (d *Driver) GetIP() (string, error) {
|
||||
// DHCP is used to get the IP, so virtualbox hosts don't have IPs unless
|
||||
// they are running
|
||||
|
@ -663,23 +724,26 @@ func (d *Driver) GetIP() (string, error) {
|
|||
return "", drivers.ErrHostIsNotRunning
|
||||
}
|
||||
|
||||
output, err := drivers.RunSSHCommandFromDriver(d, "ip addr show dev eth1")
|
||||
macAddress, err := d.getHostOnlyMACAddress()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
log.Debugf("Host-only MAC: %s\n", macAddress)
|
||||
|
||||
output, err := drivers.RunSSHCommandFromDriver(d, "ip addr show")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
log.Debugf("SSH returned: %s\nEND SSH\n", output)
|
||||
|
||||
// parse to find: inet 192.168.59.103/24 brd 192.168.59.255 scope global eth1
|
||||
lines := strings.Split(output, "\n")
|
||||
for _, line := range lines {
|
||||
vals := strings.Split(strings.TrimSpace(line), " ")
|
||||
if len(vals) >= 2 && vals[0] == "inet" {
|
||||
return vals[1][:strings.Index(vals[1], "/")], nil
|
||||
}
|
||||
ipAddress, err := d.parseIPForMACFromIPAddr(output, macAddress)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("No IP address found %s", output)
|
||||
return ipAddress, nil
|
||||
}
|
||||
|
||||
func (d *Driver) publicSSHKeyPath() string {
|
||||
|
|
|
@ -143,6 +143,49 @@ func TestGetRandomIPinSubnet(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGetHolyOnlyMACAddress(t *testing.T) {
|
||||
driver := newTestDriver("default")
|
||||
driver.VBoxManager = &VBoxManagerMock{
|
||||
args: "showvminfo default --machinereadable",
|
||||
stdOut: "unrelatedfield=whatever\nhostonlyadapter2=\"vboxnet1\"\nmacaddress2=\"004488AABBCC\"\n",
|
||||
}
|
||||
|
||||
result, err := driver.getHostOnlyMACAddress()
|
||||
expected := "004488aabbcc"
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expected, result)
|
||||
}
|
||||
|
||||
func TestGetHostOnlyMACAddressWhenNoHostOnlyAdapter(t *testing.T) {
|
||||
driver := newTestDriver("default")
|
||||
driver.VBoxManager = &VBoxManagerMock{
|
||||
args: "showvminfo default --machinereadable",
|
||||
stdOut: "unrelatedfield=whatever\n",
|
||||
}
|
||||
|
||||
result, err := driver.getHostOnlyMACAddress()
|
||||
assert.Empty(t, result)
|
||||
assert.Equal(t, err, errors.New("Machine does not have a host-only adapter"))
|
||||
}
|
||||
|
||||
func TestParseIPForMACFromIPAddr(t *testing.T) {
|
||||
driver := newTestDriver("default")
|
||||
|
||||
ipAddrOutput := "1: eth0:\n link/ether 00:44:88:aa:bb:cc\n inet 1.2.3.4/24\n2: eth1:\n link/ether 11:55:99:dd:ee:ff\n inet 5.6.7.8/24"
|
||||
|
||||
result, err := driver.parseIPForMACFromIPAddr(ipAddrOutput, "004488aabbcc")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, result, "1.2.3.4")
|
||||
|
||||
result, err = driver.parseIPForMACFromIPAddr(ipAddrOutput, "115599ddeeff")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, result, "5.6.7.8")
|
||||
|
||||
result, err = driver.parseIPForMACFromIPAddr(ipAddrOutput, "000000000000")
|
||||
assert.Empty(t, result)
|
||||
assert.Equal(t, err, errors.New("Could not find matching IP for MAC address 000000000000"))
|
||||
}
|
||||
|
||||
func TestGetIPErrors(t *testing.T) {
|
||||
var tests = []struct {
|
||||
stdOut string
|
||||
|
|
Loading…
Reference in New Issue