Skip to content
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

Fix Docker API compatibility with network alias #21013

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions libpod/container_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,12 @@ type ContainerNetworkConfig struct {
// bind-mounted inside the container.
// Conflicts with HostAdd.
UseImageHosts bool
// BaseHostsFile is the path to a hosts file, the entries from this file
// are added to the containers hosts file. As special value "image" is
// allowed which uses the /etc/hosts file from within the image and "none"
// which uses no base file at all. If it is empty we should default
// to the base_hosts_file configuration in containers.conf.
BaseHostsFile string `json:"baseHostsFile,omitempty"`
// Hosts to add in container
// Will be appended to host's host file
HostAdd []string `json:"hostsAdd,omitempty"`
Expand Down
9 changes: 8 additions & 1 deletion libpod/container_internal_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -2267,7 +2267,14 @@ func (c *Container) addHosts() error {
if err != nil {
return fmt.Errorf("failed to get container ip host entries: %w", err)
}
baseHostFile, err := etchosts.GetBaseHostFile(c.runtime.config.Containers.BaseHostsFile, c.state.Mountpoint)

// Consider container level BaseHostsFile configuration first.
// If it is empty, fallback to containers.conf level configuration.
baseHostsFileConf := c.config.BaseHostsFile
if baseHostsFileConf == "" {
baseHostsFileConf = c.runtime.config.Containers.BaseHostsFile
}
baseHostFile, err := etchosts.GetBaseHostFile(baseHostsFileConf, c.state.Mountpoint)
if err != nil {
return err
}
Expand Down
13 changes: 13 additions & 0 deletions libpod/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -2373,6 +2373,19 @@ func WithGroupEntry(groupEntry string) CtrCreateOption {
}
}

// WithBaseHostsFile sets the option to copy /etc/hosts file.
func WithBaseHostsFile(baseHostsFile string) CtrCreateOption {
return func(ctr *Container) error {
if ctr.valid {
return define.ErrCtrFinalized
}

ctr.config.BaseHostsFile = baseHostsFile

return nil
}
}

// WithMountAllDevices sets the option to mount all of a privileged container's
// host devices
func WithMountAllDevices() CtrCreateOption {
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/handlers/compat/containers_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
}
// moby always create the working directory
sg.CreateWorkingDir = true
// moby doesn't inherit /etc/hosts from host
sg.BaseHostsFile = "none"

ic := abi.ContainerEngine{Libpod: runtime}
report, err := ic.ContainerCreate(r.Context(), sg)
Expand Down
3 changes: 3 additions & 0 deletions pkg/specgen/generate/container_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,9 @@ func createContainerOptions(rt *libpod.Runtime, s *specgen.SpecGenerator, pod *l
if s.GroupEntry != "" {
options = append(options, libpod.WithGroupEntry(s.GroupEntry))
}
if s.BaseHostsFile != "" {
options = append(options, libpod.WithBaseHostsFile(s.BaseHostsFile))
}

if s.Privileged {
options = append(options, libpod.WithMountAllDevices())
Expand Down
7 changes: 7 additions & 0 deletions pkg/specgen/specgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,13 @@ type ContainerNetworkConfig struct {
// specgen is stable so we can not change this right now.
// TODO (5.0): change to pointer
UseImageHosts bool `json:"use_image_hosts"`
// BaseHostsFile is the path to a hosts file, the entries from this file
// are added to the containers hosts file. As special value "image" is
// allowed which uses the /etc/hosts file from within the image and "none"
// which uses no base file at all. If it is empty we should default
// to the base_hosts_file configuration in containers.conf.
// Optional.
BaseHostsFile string `json:"base_hosts_file,omitempty"`
// HostAdd is a set of hosts which will be added to the container's
// /etc/hosts file.
// Conflicts with UseImageHosts.
Expand Down
10 changes: 10 additions & 0 deletions test/compose/etc_hosts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
etc hosts
===========

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.

Validation
------------

* 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.
* The hostname is resolved to IP address of the alias.
19 changes: 19 additions & 0 deletions test/compose/etc_hosts/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: '3.3'

services:
test:
image: alpine
command: ["top"]
hostname: foobar
networks:
net1:
aliases:
- foobar

networks:
net1:
driver: bridge
ipam:
driver: default
config:
- subnet: 10.123.0.0/24
2 changes: 2 additions & 0 deletions test/compose/etc_hosts/hosts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
127.0.0.1 localhost
127.0.0.1 foobar
5 changes: 5 additions & 0 deletions test/compose/etc_hosts/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
if ! is_rootless; then
mount --bind $TEST_ROOTDIR/etc_hosts/hosts /etc/hosts
else
$PODMAN_BIN unshare mount --bind $TEST_ROOTDIR/etc_hosts/hosts /etc/hosts
fi
5 changes: 5 additions & 0 deletions test/compose/etc_hosts/teardown.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
if ! is_rootless; then
umount /etc/hosts
else
$PODMAN_BIN unshare umount /etc/hosts
fi
12 changes: 12 additions & 0 deletions test/compose/etc_hosts/tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# -*- bash -*-

ctr_name="etc_hosts_test_1"
if [ "$TEST_FLAVOR" = "compose_v2" ]; then
ctr_name="etc_hosts-test-1"
fi

podman exec "$ctr_name" sh -c 'grep "foobar" /etc/hosts'
like "$output" "10\.123\.0\." "$testname : no entries are copied from the host"

podman exec "$ctr_name" sh -c 'getent hosts foobar | awk "{print \$1}"'
like "$output" "10\.123\.0\." "$testname : hostname is resolved to IP address of the alias"
2 changes: 1 addition & 1 deletion test/compose/test-compose
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ function start_service() {

$PODMAN_BIN \
--log-level debug \
--storage-driver=vfs \
--storage-driver=vfs \
--root $WORKDIR/root \
--runroot $WORKDIR/runroot \
--cgroup-manager=systemd \
Expand Down