Skip to content

Commit

Permalink
Merge pull request moby#2445 from kdomanski/ipv6-addr-in-hosts
Browse files Browse the repository at this point in the history
etchosts: include the container's IPv6 address if available
  • Loading branch information
selansen authored Dec 4, 2019
2 parents 9b62a8a + c4fcd70 commit f55f6f8
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 9 deletions.
24 changes: 19 additions & 5 deletions libnetwork/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,11 +498,14 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) (err error) {
}

if doUpdateHostsFile(n, sb) {
address := ""
if ip := ep.getFirstInterfaceAddress(); ip != nil {
address = ip.String()
var addresses []string
if ip := ep.getFirstInterfaceIPv4Address(); ip != nil {
addresses = append(addresses, ip.String())
}
if err = sb.updateHostsFile(address); err != nil {
if ip := ep.getFirstInterfaceIPv6Address(); ip != nil {
addresses = append(addresses, ip.String())
}
if err = sb.updateHostsFile(addresses); err != nil {
return err
}
}
Expand Down Expand Up @@ -912,7 +915,7 @@ func (ep *endpoint) getSandbox() (*sandbox, bool) {
return ps, ok
}

func (ep *endpoint) getFirstInterfaceAddress() net.IP {
func (ep *endpoint) getFirstInterfaceIPv4Address() net.IP {
ep.Lock()
defer ep.Unlock()

Expand All @@ -923,6 +926,17 @@ func (ep *endpoint) getFirstInterfaceAddress() net.IP {
return nil
}

func (ep *endpoint) getFirstInterfaceIPv6Address() net.IP {
ep.Lock()
defer ep.Unlock()

if ep.iface.addrv6 != nil {
return ep.iface.addrv6.IP
}

return nil
}

// EndpointOptionGeneric function returns an option setter for a Generic option defined
// in a Dictionary of Key-Value pair
func EndpointOptionGeneric(generic map[string]interface{}) EndpointOption {
Expand Down
76 changes: 76 additions & 0 deletions libnetwork/endpoint_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// +build !windows

package libnetwork

import (
"io/ioutil"
"os"
"testing"

"github.com/docker/libnetwork/ipamapi"
"github.com/docker/libnetwork/osl"
"github.com/docker/libnetwork/testutils"
)

func TestHostsEntries(t *testing.T) {
if !testutils.IsRunningInContainer() {
defer testutils.SetupTestOSContext(t)()
}

expectedHostsFile := `127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.222.2 somehost.example.com somehost
fe90::2 somehost.example.com somehost
`

opts := []NetworkOption{NetworkOptionEnableIPv6(true), NetworkOptionIpam(ipamapi.DefaultIPAM, "",
[]*IpamConf{{PreferredPool: "192.168.222.0/24", Gateway: "192.168.222.1"}},
[]*IpamConf{{PreferredPool: "fe90::/64", Gateway: "fe90::1"}},
nil)}

c, nws := getTestEnv(t, opts)
ctrlr := c.(*controller)

hostsFile, err := ioutil.TempFile("", "")
if err != nil {
t.Fatal(err)
}
defer os.Remove(hostsFile.Name())

sbx, err := ctrlr.NewSandbox("sandbox1", OptionHostsPath(hostsFile.Name()), OptionHostname("somehost.example.com"))
if err != nil {
t.Fatal(err)
}

ep1, err := nws[0].CreateEndpoint("ep1")
if err != nil {
t.Fatal(err)
}

if err := ep1.Join(sbx, JoinOptionPriority(ep1, 1)); err != nil {
t.Fatal(err)
}

data, err := ioutil.ReadFile(hostsFile.Name())
if err != nil {
t.Fatal(err)
}

if string(data) != expectedHostsFile {
t.Fatalf("expected the hosts file to read:\n%q\nbut instead got the following:\n%q\n", expectedHostsFile, string(data))
}

if err := sbx.Delete(); err != nil {
t.Fatal(err)
}

if len(ctrlr.sandboxes) != 0 {
t.Fatalf("controller sandboxes is not empty. len = %d", len(ctrlr.sandboxes))
}

osl.GC()
}
9 changes: 6 additions & 3 deletions libnetwork/sandbox_dns_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ func (sb *sandbox) buildHostsFile() error {
return etchosts.Build(sb.config.hostsPath, "", sb.config.hostName, sb.config.domainName, extraContent)
}

func (sb *sandbox) updateHostsFile(ifaceIP string) error {
if ifaceIP == "" {
func (sb *sandbox) updateHostsFile(ifaceIPs []string) error {
if ifaceIPs == nil || len(ifaceIPs) == 0 {
return nil
}

Expand All @@ -120,7 +120,10 @@ func (sb *sandbox) updateHostsFile(ifaceIP string) error {
mhost = fmt.Sprintf("%s %s", fqdn, parts[0])
}

extraContent := []etchosts.Record{{Hosts: mhost, IP: ifaceIP}}
var extraContent []etchosts.Record
for _, ip := range ifaceIPs {
extraContent = append(extraContent, etchosts.Record{Hosts: mhost, IP: ip})
}

sb.addHostsEntries(extraContent)
return nil
Expand Down
2 changes: 1 addition & 1 deletion libnetwork/sandbox_dns_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func (sb *sandbox) setupResolutionFiles() error {
func (sb *sandbox) restorePath() {
}

func (sb *sandbox) updateHostsFile(ifaceIP string) error {
func (sb *sandbox) updateHostsFile(ifaceIP []string) error {
return nil
}

Expand Down

0 comments on commit f55f6f8

Please sign in to comment.