From 828b5474914c4036d3a6135c63604d223ced3610 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Tue, 28 Jul 2020 09:18:21 -0400 Subject: Specifying --ipc=host --pid=host is broken For some reason we were overwriting memory when handling both --pid=host and --ipc=host. Simplified the code to handle this correctly, and add test to make sure it does not happen again. Signed-off-by: Daniel J Walsh --- test/e2e/run_ns_test.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'test') diff --git a/test/e2e/run_ns_test.go b/test/e2e/run_ns_test.go index 1c1b5cfbb..7113fa69e 100644 --- a/test/e2e/run_ns_test.go +++ b/test/e2e/run_ns_test.go @@ -4,6 +4,7 @@ package integration import ( "os" + "os/exec" "strings" . "github.com/containers/libpod/v2/test/utils" @@ -104,4 +105,34 @@ var _ = Describe("Podman run ns", func() { session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) }) + + It("podman run --ipc=host --pid=host", func() { + cmd := exec.Command("ls", "-l", "/proc/self/ns/pid") + res, err := cmd.Output() + Expect(err).To(BeNil()) + fields := strings.Split(string(res), " ") + hostPidNS := strings.TrimSuffix(fields[len(fields)-1], "\n") + + cmd = exec.Command("ls", "-l", "/proc/self/ns/ipc") + res, err = cmd.Output() + Expect(err).To(BeNil()) + fields = strings.Split(string(res), " ") + hostIpcNS := strings.TrimSuffix(fields[len(fields)-1], "\n") + + session := podmanTest.Podman([]string{"run", "--ipc=host", "--pid=host", ALPINE, "ls", "-l", "/proc/self/ns/pid"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + fields = strings.Split(session.OutputToString(), " ") + ctrPidNS := strings.TrimSuffix(fields[len(fields)-1], "\n") + + session = podmanTest.Podman([]string{"run", "--ipc=host", "--pid=host", ALPINE, "ls", "-l", "/proc/self/ns/ipc"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + fields = strings.Split(session.OutputToString(), " ") + ctrIpcNS := strings.TrimSuffix(fields[len(fields)-1], "\n") + + Expect(hostPidNS).To(Equal(ctrPidNS)) + Expect(hostIpcNS).To(Equal(ctrIpcNS)) + }) + }) -- cgit v1.2.3-54-g00ecf From da752a7ed32f90a3f187eeb5f3f372889561a021 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Thu, 23 Jul 2020 16:43:43 -0400 Subject: Binding the same container port to >1 host port is OK The initial version of the new port code mistakenly restricted this, so un-restrict it. We still need to maintain the map of container ports, unfortunately (need to verify if the port in question is a duplicate, for example). Fixes #7062 Signed-off-by: Matthew Heon --- pkg/specgen/generate/ports.go | 15 ++++++++------- test/e2e/run_networking_test.go | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/pkg/specgen/generate/ports.go b/pkg/specgen/generate/ports.go index c8d1c27c5..2125c6b9f 100644 --- a/pkg/specgen/generate/ports.go +++ b/pkg/specgen/generate/ports.go @@ -123,19 +123,20 @@ func parsePortMapping(portMappings []specgen.PortMapping) ([]ocicni.PortMapping, postAssignHostPort = true } } else { - testCPort := ctrPortMap[cPort] - if testCPort != 0 && testCPort != hPort { - // This is an attempt to redefine a port - return nil, nil, nil, errors.Errorf("conflicting port mappings for container port %d (protocol %s)", cPort, p) - } - ctrPortMap[cPort] = hPort - testHPort := hostPortMap[hPort] if testHPort != 0 && testHPort != cPort { return nil, nil, nil, errors.Errorf("conflicting port mappings for host port %d (protocol %s)", hPort, p) } hostPortMap[hPort] = cPort + // Mapping a container port to multiple + // host ports is allowed. + // We only store the latest of these in + // the container port map - we don't + // need to know all of them, just one. + testCPort := ctrPortMap[cPort] + ctrPortMap[cPort] = hPort + // If we have an exact duplicate, just continue if testCPort == hPort && testHPort == cPort { continue diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index 9357145ab..40cc9e1e6 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -222,6 +222,22 @@ var _ = Describe("Podman run networking", func() { Expect(inspectOut[0].NetworkSettings.Ports["8080/tcp"][0].HostIP).To(Equal("")) }) + It("podman run -p 8080:8080 -p 8081:8080", func() { + name := "testctr" + session := podmanTest.Podman([]string{"create", "-t", "-p", "4000:8080", "-p", "8000:8080", "--name", name, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + inspectOut := podmanTest.InspectContainer(name) + Expect(len(inspectOut)).To(Equal(1)) + Expect(len(inspectOut[0].NetworkSettings.Ports)).To(Equal(1)) + Expect(len(inspectOut[0].NetworkSettings.Ports["8080/tcp"])).To(Equal(2)) + + hp1 := inspectOut[0].NetworkSettings.Ports["8080/tcp"][0].HostPort + hp2 := inspectOut[0].NetworkSettings.Ports["8080/tcp"][1].HostPort + + // We can't guarantee order + Expect((hp1 == "4000" && hp2 == "8000") || (hp1 == "8000" && hp2 == "4000")).To(BeTrue()) + }) + It("podman run network expose host port 80 to container port 8000", func() { SkipIfRootless() session := podmanTest.Podman([]string{"run", "-dt", "-p", "80:8000", ALPINE, "/bin/sh"}) -- cgit v1.2.3-54-g00ecf From 2cc9af369290428ca3d5e96bee5b65262b57a1f7 Mon Sep 17 00:00:00 2001 From: Ashley Cui Date: Thu, 30 Jul 2020 13:50:50 -0400 Subject: add {{.RunningFor}} placeholder in ps --format For docker compatibility Signed-off-by: Ashley Cui --- cmd/podman/containers/ps.go | 4 ++++ test/e2e/ps_test.go | 8 ++++++++ 2 files changed, 12 insertions(+) (limited to 'test') diff --git a/cmd/podman/containers/ps.go b/cmd/podman/containers/ps.go index 7c84cbae1..34f06d349 100644 --- a/cmd/podman/containers/ps.go +++ b/cmd/podman/containers/ps.go @@ -307,6 +307,10 @@ func (l psReporter) Status() string { return l.State() } +func (l psReporter) RunningFor() string { + return l.CreatedHuman() +} + // Command returns the container command in string format func (l psReporter) Command() string { command := strings.Join(l.ListContainer.Command, " ") diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go index 152c85704..48746f30c 100644 --- a/test/e2e/ps_test.go +++ b/test/e2e/ps_test.go @@ -476,5 +476,13 @@ var _ = Describe("Podman ps", func() { session.WaitWithDefaultTimeout() Expect(session.OutputToString()).To(ContainSubstring("echo very long cr...")) }) + It("podman ps --format {{RunningFor}}", func() { + _, ec, _ := podmanTest.RunLsContainer("") + Expect(ec).To(Equal(0)) + result := podmanTest.Podman([]string{"ps", "-a", "--format", "{{.RunningFor}}"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + Expect(result.OutputToString()).To(ContainSubstring("ago")) + }) }) -- cgit v1.2.3-54-g00ecf From 2d715405182f67937c152d4cd74b282a2e6ca786 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Thu, 30 Jul 2020 22:59:45 +0200 Subject: volumes: do not recurse when chowning keep the file ownership when chowning and honor the user namespace mappings. Closes: https://github.com/containers/podman/issues/7130 Signed-off-by: Giuseppe Scrivano Signed-off-by: Matthew Heon --- libpod/container_internal.go | 35 ++++++----- test/system/070-build.bats | 134 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 13 deletions(-) (limited to 'test') diff --git a/libpod/container_internal.go b/libpod/container_internal.go index e277a88c5..675311461 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -1521,9 +1521,6 @@ func (c *Container) chownVolume(volumeName string) error { return errors.Wrapf(err, "error retrieving named volume %s for container %s", volumeName, c.ID()) } - uid := int(c.config.Spec.Process.User.UID) - gid := int(c.config.Spec.Process.User.GID) - vol.lock.Lock() defer vol.lock.Unlock() @@ -1534,22 +1531,34 @@ func (c *Container) chownVolume(volumeName string) error { if vol.state.NeedsChown { vol.state.NeedsChown = false + + uid := int(c.config.Spec.Process.User.UID) + gid := int(c.config.Spec.Process.User.GID) + + if c.config.IDMappings.UIDMap != nil { + p := idtools.IDPair{ + UID: uid, + GID: gid, + } + mappings := idtools.NewIDMappingsFromMaps(c.config.IDMappings.UIDMap, c.config.IDMappings.GIDMap) + newPair, err := mappings.ToHost(p) + if err != nil { + return errors.Wrapf(err, "error mapping user %d:%d", uid, gid) + } + uid = newPair.UID + gid = newPair.GID + } + vol.state.UIDChowned = uid vol.state.GIDChowned = gid if err := vol.save(); err != nil { return err } - err := filepath.Walk(vol.MountPoint(), func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if err := os.Lchown(path, uid, gid); err != nil { - return err - } - return nil - }) - if err != nil { + + mountPoint := vol.MountPoint() + + if err := os.Lchown(mountPoint, uid, gid); err != nil { return err } } diff --git a/test/system/070-build.bats b/test/system/070-build.bats index 7d6660270..6879b956f 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -98,6 +98,140 @@ EOF is "$output" ".*error building at STEP .*: source can't be a URL for COPY" } +@test "podman build - workdir, cmd, env, label" { + tmpdir=$PODMAN_TMPDIR/build-test + mkdir -p $tmpdir + + # Random workdir, and multiple random strings to verify command & env + workdir=/$(random_string 10) + s_echo=$(random_string 15) + s_env1=$(random_string 20) + s_env2=$(random_string 25) + s_env3=$(random_string 30) + s_env4=$(random_string 40) + + # Label name: make sure it begins with a letter! jq barfs if you + # try to ask it for '.foo.xyz', i.e. any string beginning with digit + label_name=l$(random_string 8) + label_value=$(random_string 12) + + # Command to run on container startup with no args + cat >$tmpdir/mycmd <$PODMAN_TMPDIR/env-file <$tmpdir/Containerfile < expect=<$expect}>" + is "$actual" "$expect" "jq .Config.$field" + done + + # Bad symlink in volume. Prior to #7094, well, we wouldn't actually + # get here because any 'podman run' on a volume that had symlinks, + # be they dangling or valid, would barf with + # Error: chown /_data/symlink: ENOENT + run_podman run --rm build_test stat -c'%u:%g:%N' /a/b/c/badsymlink + is "$output" "1:2:'/a/b/c/badsymlink' -> '/no/such/nonesuch'" \ + "bad symlink to nonexistent file is chowned and preserved" + + run_podman run --rm build_test stat -c'%u:%g:%N' /a/b/c/goodsymlink + is "$output" "1:2:'/a/b/c/goodsymlink' -> '/bin/mydefaultcmd'" \ + "good symlink to existing file is chowned and preserved" + + run_podman run --rm build_test stat -c'%u:%g' /bin/mydefaultcmd + is "$output" "2:3" "target of symlink is not chowned" + + run_podman run --rm build_test stat -c'%u:%g:%N' /a/b/c/myfile + is "$output" "4:5:/a/b/c/myfile" "file in volume is chowned" + + # Clean up + run_podman rmi -f build_test +} + @test "podman build - stdin test" { if is_remote && is_rootless; then skip "unreliable with podman-remote and rootless; #2972" -- cgit v1.2.3-54-g00ecf From a9a55be991fa8f06cf266bd84a72589713a71ac9 Mon Sep 17 00:00:00 2001 From: Matthew Heon Date: Fri, 31 Jul 2020 12:39:55 -0400 Subject: Disable a nonfunctional build test The amount of drift in the system tests on v2.0 is starting to become difficult to deal with. 2.1.0 can't come soon enough. Signed-off-by: Matthew Heon --- test/system/070-build.bats | 134 --------------------------------------------- 1 file changed, 134 deletions(-) (limited to 'test') diff --git a/test/system/070-build.bats b/test/system/070-build.bats index 6879b956f..7d6660270 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -98,140 +98,6 @@ EOF is "$output" ".*error building at STEP .*: source can't be a URL for COPY" } -@test "podman build - workdir, cmd, env, label" { - tmpdir=$PODMAN_TMPDIR/build-test - mkdir -p $tmpdir - - # Random workdir, and multiple random strings to verify command & env - workdir=/$(random_string 10) - s_echo=$(random_string 15) - s_env1=$(random_string 20) - s_env2=$(random_string 25) - s_env3=$(random_string 30) - s_env4=$(random_string 40) - - # Label name: make sure it begins with a letter! jq barfs if you - # try to ask it for '.foo.xyz', i.e. any string beginning with digit - label_name=l$(random_string 8) - label_value=$(random_string 12) - - # Command to run on container startup with no args - cat >$tmpdir/mycmd <$PODMAN_TMPDIR/env-file <$tmpdir/Containerfile < expect=<$expect}>" - is "$actual" "$expect" "jq .Config.$field" - done - - # Bad symlink in volume. Prior to #7094, well, we wouldn't actually - # get here because any 'podman run' on a volume that had symlinks, - # be they dangling or valid, would barf with - # Error: chown /_data/symlink: ENOENT - run_podman run --rm build_test stat -c'%u:%g:%N' /a/b/c/badsymlink - is "$output" "1:2:'/a/b/c/badsymlink' -> '/no/such/nonesuch'" \ - "bad symlink to nonexistent file is chowned and preserved" - - run_podman run --rm build_test stat -c'%u:%g:%N' /a/b/c/goodsymlink - is "$output" "1:2:'/a/b/c/goodsymlink' -> '/bin/mydefaultcmd'" \ - "good symlink to existing file is chowned and preserved" - - run_podman run --rm build_test stat -c'%u:%g' /bin/mydefaultcmd - is "$output" "2:3" "target of symlink is not chowned" - - run_podman run --rm build_test stat -c'%u:%g:%N' /a/b/c/myfile - is "$output" "4:5:/a/b/c/myfile" "file in volume is chowned" - - # Clean up - run_podman rmi -f build_test -} - @test "podman build - stdin test" { if is_remote && is_rootless; then skip "unreliable with podman-remote and rootless; #2972" -- cgit v1.2.3-54-g00ecf