Skip to content

Commit db68764

Browse files
committed
Fix Docker API compatibility with network alias (#17167)
* Add BaseHostsFile to container configuration * Do not copy /etc/hosts file from host when creating a container using Docker API Signed-off-by: Gavin Lam <[email protected]>
1 parent 077b000 commit db68764

File tree

13 files changed

+93
-2
lines changed

13 files changed

+93
-2
lines changed

libpod/container_config.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,12 @@ type ContainerNetworkConfig struct {
291291
// bind-mounted inside the container.
292292
// Conflicts with HostAdd.
293293
UseImageHosts bool
294+
// BaseHostsFile is the path to a hosts file, the entries from this file
295+
// are added to the containers hosts file. As special value "image" is
296+
// allowed which uses the /etc/hosts file from within the image and "none"
297+
// which uses no base file at all. If it is empty we should default
298+
// to the base_hosts_file configuration in containers.conf.
299+
BaseHostsFile string `json:"baseHostsFile,omitempty"`
294300
// Hosts to add in container
295301
// Will be appended to host's host file
296302
HostAdd []string `json:"hostsAdd,omitempty"`

libpod/container_internal_common.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2267,7 +2267,14 @@ func (c *Container) addHosts() error {
22672267
if err != nil {
22682268
return fmt.Errorf("failed to get container ip host entries: %w", err)
22692269
}
2270-
baseHostFile, err := etchosts.GetBaseHostFile(c.runtime.config.Containers.BaseHostsFile, c.state.Mountpoint)
2270+
2271+
// Consider container level BaseHostsFile configuration first.
2272+
// If it is empty, fallback to containers.conf level configuration.
2273+
baseHostsFileConf := c.config.BaseHostsFile
2274+
if baseHostsFileConf == "" {
2275+
baseHostsFileConf = c.runtime.config.Containers.BaseHostsFile
2276+
}
2277+
baseHostFile, err := etchosts.GetBaseHostFile(baseHostsFileConf, c.state.Mountpoint)
22712278
if err != nil {
22722279
return err
22732280
}

libpod/options.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2373,6 +2373,19 @@ func WithGroupEntry(groupEntry string) CtrCreateOption {
23732373
}
23742374
}
23752375

2376+
// WithBaseHostsFile sets the option to copy /etc/hosts file.
2377+
func WithBaseHostsFile(baseHostsFile string) CtrCreateOption {
2378+
return func(ctr *Container) error {
2379+
if ctr.valid {
2380+
return define.ErrCtrFinalized
2381+
}
2382+
2383+
ctr.config.BaseHostsFile = baseHostsFile
2384+
2385+
return nil
2386+
}
2387+
}
2388+
23762389
// WithMountAllDevices sets the option to mount all of a privileged container's
23772390
// host devices
23782391
func WithMountAllDevices() CtrCreateOption {

pkg/api/handlers/compat/containers_create.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
116116
}
117117
// moby always create the working directory
118118
sg.CreateWorkingDir = true
119+
// moby doesn't inherit /etc/hosts from host
120+
sg.BaseHostsFile = "none"
119121

120122
ic := abi.ContainerEngine{Libpod: runtime}
121123
report, err := ic.ContainerCreate(r.Context(), sg)

pkg/specgen/generate/container_create.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,9 @@ func createContainerOptions(rt *libpod.Runtime, s *specgen.SpecGenerator, pod *l
378378
if s.GroupEntry != "" {
379379
options = append(options, libpod.WithGroupEntry(s.GroupEntry))
380380
}
381+
if s.BaseHostsFile != "" {
382+
options = append(options, libpod.WithBaseHostsFile(s.BaseHostsFile))
383+
}
381384

382385
if s.Privileged {
383386
options = append(options, libpod.WithMountAllDevices())

pkg/specgen/specgen.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,13 @@ type ContainerNetworkConfig struct {
507507
// specgen is stable so we can not change this right now.
508508
// TODO (5.0): change to pointer
509509
UseImageHosts bool `json:"use_image_hosts"`
510+
// BaseHostsFile is the path to a hosts file, the entries from this file
511+
// are added to the containers hosts file. As special value "image" is
512+
// allowed which uses the /etc/hosts file from within the image and "none"
513+
// which uses no base file at all. If it is empty we should default
514+
// to the base_hosts_file configuration in containers.conf.
515+
// Optional.
516+
BaseHostsFile string `json:"base_hosts_file,omitempty"`
510517
// HostAdd is a set of hosts which will be added to the container's
511518
// /etc/hosts file.
512519
// Conflicts with UseImageHosts.

test/compose/etc_hosts/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
etc hosts
2+
===========
3+
4+
This test mounts a /etc/hosts file in the host containing an entry `foobar`, then create a container with an alias of the same hostname.
5+
6+
Validation
7+
------------
8+
9+
* No /etc/hosts entries are copied from the host. There should be only one entry of the hostname, which is IP address of the alias.
10+
* The hostname is resolved to IP address of the alias.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
version: '3.3'
2+
3+
services:
4+
test:
5+
image: alpine
6+
command: ["top"]
7+
hostname: foobar
8+
networks:
9+
net1:
10+
aliases:
11+
- foobar
12+
13+
networks:
14+
net1:
15+
driver: bridge
16+
ipam:
17+
driver: default
18+
config:
19+
- subnet: 10.123.0.0/24

test/compose/etc_hosts/hosts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
127.0.0.1 localhost
2+
127.0.0.1 foobar

test/compose/etc_hosts/setup.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
if ! is_rootless; then
2+
mount --bind $TEST_ROOTDIR/etc_hosts/hosts /etc/hosts
3+
else
4+
$PODMAN_BIN unshare mount --bind $TEST_ROOTDIR/etc_hosts/hosts /etc/hosts
5+
fi

0 commit comments

Comments
 (0)