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
|
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) {
|
func (d *Driver) GetIP() (string, error) {
|
||||||
// DHCP is used to get the IP, so virtualbox hosts don't have IPs unless
|
// DHCP is used to get the IP, so virtualbox hosts don't have IPs unless
|
||||||
// they are running
|
// they are running
|
||||||
|
@ -663,23 +724,26 @@ func (d *Driver) GetIP() (string, error) {
|
||||||
return "", drivers.ErrHostIsNotRunning
|
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 {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("SSH returned: %s\nEND SSH\n", output)
|
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
|
ipAddress, err := d.parseIPForMACFromIPAddr(output, macAddress)
|
||||||
lines := strings.Split(output, "\n")
|
if err != nil {
|
||||||
for _, line := range lines {
|
return "", err
|
||||||
vals := strings.Split(strings.TrimSpace(line), " ")
|
|
||||||
if len(vals) >= 2 && vals[0] == "inet" {
|
|
||||||
return vals[1][:strings.Index(vals[1], "/")], nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", fmt.Errorf("No IP address found %s", output)
|
return ipAddress, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) publicSSHKeyPath() string {
|
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) {
|
func TestGetIPErrors(t *testing.T) {
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
stdOut string
|
stdOut string
|
||||||
|
|
Loading…
Reference in New Issue