summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2018-12-13 08:05:41 -0800
committerGitHub <noreply@github.com>2018-12-13 08:05:41 -0800
commitbff29f5475f5b90a2a1f78bd0fe8b2909756774d (patch)
tree1471bf0628964b666e78282cfeac5c3515f755b5
parente3a1a7efca7f64b125fcd4f627a871bc699b5888 (diff)
parentc93ad3762c402c56d6cbb1c7a6f1202b4962eeb4 (diff)
downloadpodman-bff29f5475f5b90a2a1f78bd0fe8b2909756774d.tar.gz
podman-bff29f5475f5b90a2a1f78bd0fe8b2909756774d.tar.bz2
podman-bff29f5475f5b90a2a1f78bd0fe8b2909756774d.zip
Merge pull request #1988 from mheon/use_dependency_resolv
Containers sharing a netns should share resolv/hosts
-rw-r--r--libpod/container.go2
-rw-r--r--libpod/container_internal_linux.go75
-rw-r--r--test/e2e/run_networking_test.go33
3 files changed, 91 insertions, 19 deletions
diff --git a/libpod/container.go b/libpod/container.go
index b5346e581..18d867f41 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -1003,7 +1003,7 @@ func (c *Container) IsReadOnly() bool {
// NetworkDisabled returns whether the container is running with a disabled network
func (c *Container) NetworkDisabled() (bool, error) {
if c.config.NetNsCtr != "" {
- container, err := c.runtime.LookupContainer(c.config.NetNsCtr)
+ container, err := c.runtime.state.Container(c.config.NetNsCtr)
if err != nil {
return false, err
}
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 4f2955110..93d20491e 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -26,6 +26,7 @@ import (
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/secrets"
"github.com/containers/storage/pkg/idtools"
+ "github.com/mrunalp/fileutils"
"github.com/opencontainers/runc/libcontainer/user"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
@@ -645,28 +646,68 @@ func (c *Container) makeBindMounts() error {
}
if !netDisabled {
- // Make /etc/resolv.conf
- if _, ok := c.state.BindMounts["/etc/resolv.conf"]; ok {
- // If it already exists, delete so we can recreate
+ // If /etc/resolv.conf and /etc/hosts exist, delete them so we
+ // will recreate
+ if path, ok := c.state.BindMounts["/etc/resolv.conf"]; ok {
+ if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
+ return errors.Wrapf(err, "error removing container %s resolv.conf", c.ID())
+ }
delete(c.state.BindMounts, "/etc/resolv.conf")
}
- newResolv, err := c.generateResolvConf()
- if err != nil {
- return errors.Wrapf(err, "error creating resolv.conf for container %s", c.ID())
- }
- c.state.BindMounts["/etc/resolv.conf"] = newResolv
-
- // Make /etc/hosts
- if _, ok := c.state.BindMounts["/etc/hosts"]; ok {
- // If it already exists, delete so we can recreate
+ if path, ok := c.state.BindMounts["/etc/hosts"]; ok {
+ if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
+ return errors.Wrapf(err, "error removing container %s hosts", c.ID())
+ }
delete(c.state.BindMounts, "/etc/hosts")
}
- newHosts, err := c.generateHosts()
- if err != nil {
- return errors.Wrapf(err, "error creating hosts file for container %s", c.ID())
- }
- c.state.BindMounts["/etc/hosts"] = newHosts
+ if c.config.NetNsCtr != "" {
+ // We share a net namespace
+ // We want /etc/resolv.conf and /etc/hosts from the
+ // other container
+ depCtr, err := c.runtime.state.Container(c.config.NetNsCtr)
+ if err != nil {
+ return errors.Wrapf(err, "error fetching dependency %s of container %s", c.config.NetNsCtr, c.ID())
+ }
+
+ // We need that container's bind mounts
+ bindMounts, err := depCtr.BindMounts()
+ if err != nil {
+ return errors.Wrapf(err, "error fetching bind mounts from dependency %s of container %s", depCtr.ID(), c.ID())
+ }
+
+ // The other container may not have a resolv.conf or /etc/hosts
+ // If it doesn't, don't copy them
+ resolvPath, exists := bindMounts["/etc/resolv.conf"]
+ if exists {
+ resolvDest := filepath.Join(c.state.RunDir, "resolv.conf")
+ if err := fileutils.CopyFile(resolvPath, resolvDest); err != nil {
+ return errors.Wrapf(err, "error copying resolv.conf from dependency container %s of container %s", depCtr.ID(), c.ID())
+ }
+ c.state.BindMounts["/etc/resolv.conf"] = resolvDest
+ }
+
+ hostsPath, exists := bindMounts["/etc/hosts"]
+ if exists {
+ hostsDest := filepath.Join(c.state.RunDir, "hosts")
+ if err := fileutils.CopyFile(hostsPath, hostsDest); err != nil {
+ return errors.Wrapf(err, "error copying hosts file from dependency container %s of container %s", depCtr.ID(), c.ID())
+ }
+ c.state.BindMounts["/etc/hosts"] = hostsDest
+ }
+ } else {
+ newResolv, err := c.generateResolvConf()
+ if err != nil {
+ return errors.Wrapf(err, "error creating resolv.conf for container %s", c.ID())
+ }
+ c.state.BindMounts["/etc/resolv.conf"] = newResolv
+
+ newHosts, err := c.generateHosts()
+ if err != nil {
+ return errors.Wrapf(err, "error creating hosts file for container %s", c.ID())
+ }
+ c.state.BindMounts["/etc/hosts"] = newHosts
+ }
}
// SHM is always added when we mount the container
diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go
index 1b05ac031..68b1f06de 100644
--- a/test/e2e/run_networking_test.go
+++ b/test/e2e/run_networking_test.go
@@ -9,7 +9,7 @@ import (
. "github.com/onsi/gomega"
)
-var _ = Describe("Podman rmi", func() {
+var _ = Describe("Podman run networking", func() {
var (
tempdir string
err error
@@ -145,4 +145,35 @@ var _ = Describe("Podman rmi", func() {
match, _ := session.GrepString("foobar")
Expect(match).Should(BeTrue())
})
+
+ It("podman run --net container: copies hosts and resolv", func() {
+ ctrName := "ctr1"
+ ctr1 := podmanTest.RunTopContainer(ctrName)
+ ctr1.WaitWithDefaultTimeout()
+ Expect(ctr1.ExitCode()).To(Equal(0))
+
+ // Exec in and modify /etc/resolv.conf and /etc/hosts
+ exec1 := podmanTest.Podman([]string{"exec", ctrName, "sh", "-c", "echo nameserver 192.0.2.1 > /etc/resolv.conf"})
+ exec1.WaitWithDefaultTimeout()
+ Expect(exec1.ExitCode()).To(Equal(0))
+
+ exec2 := podmanTest.Podman([]string{"exec", ctrName, "sh", "-c", "echo 192.0.2.2 test1 > /etc/hosts"})
+ exec2.WaitWithDefaultTimeout()
+ Expect(exec2.ExitCode()).To(Equal(0))
+
+ ctrName2 := "ctr2"
+ ctr2 := podmanTest.Podman([]string{"run", "-d", "--net=container:" + ctrName, "--name", ctrName2, ALPINE, "top"})
+ ctr2.WaitWithDefaultTimeout()
+ Expect(ctr2.ExitCode()).To(Equal(0))
+
+ exec3 := podmanTest.Podman([]string{"exec", "-i", ctrName2, "cat", "/etc/resolv.conf"})
+ exec3.WaitWithDefaultTimeout()
+ Expect(exec3.ExitCode()).To(Equal(0))
+ Expect(exec3.OutputToString()).To(ContainSubstring("nameserver 192.0.2.1"))
+
+ exec4 := podmanTest.Podman([]string{"exec", "-i", ctrName2, "cat", "/etc/hosts"})
+ exec4.WaitWithDefaultTimeout()
+ Expect(exec4.ExitCode()).To(Equal(0))
+ Expect(exec4.OutputToString()).To(ContainSubstring("192.0.2.2 test1"))
+ })
})