diff options
-rw-r--r-- | cmd/podman/common/specgen.go | 11 | ||||
-rw-r--r-- | cmd/podman/containers/cp.go | 4 | ||||
-rw-r--r-- | pkg/api/server/register_containers.go | 22 | ||||
-rw-r--r-- | pkg/domain/infra/abi/archive.go | 7 | ||||
-rw-r--r-- | pkg/rootless/rootless_linux.c | 6 | ||||
-rw-r--r-- | test/e2e/run_memory_test.go | 24 | ||||
-rw-r--r-- | test/system/065-cp.bats | 26 |
7 files changed, 79 insertions, 21 deletions
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go index 975c76fd9..eff8b43aa 100644 --- a/cmd/podman/common/specgen.go +++ b/cmd/podman/common/specgen.go @@ -148,17 +148,16 @@ func getMemoryLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.Linu } if m := c.MemorySwap; len(m) > 0 { var ms int64 - if m == "-1" { - ms = int64(-1) - s.ResourceLimits.Memory.Swap = &ms - } else { + // only set memory swap if it was set + // -1 indicates unlimited + if m != "-1" { ms, err = units.RAMInBytes(m) + memory.Swap = &ms if err != nil { return nil, errors.Wrapf(err, "invalid value for memory") } + hasLimits = true } - memory.Swap = &ms - hasLimits = true } if m := c.KernelMemory; len(m) > 0 { mk, err := units.RAMInBytes(m) diff --git a/cmd/podman/containers/cp.go b/cmd/podman/containers/cp.go index 69b61a06c..5db05719c 100644 --- a/cmd/podman/containers/cp.go +++ b/cmd/podman/containers/cp.go @@ -311,8 +311,8 @@ func copyToContainer(container string, containerPath string, hostPath string) er } getOptions := buildahCopiah.GetOptions{ - // Unless the specified path ends with ".", we want to copy the base directory. - KeepDirectoryNames: !strings.HasSuffix(hostPath, "."), + // Unless the specified points to ".", we want to copy the base directory. + KeepDirectoryNames: hostInfo.IsDir && filepath.Base(hostPath) != ".", } if !hostInfo.IsDir && (!containerInfo.IsDir || containerInfoErr != nil) { // If we're having a file-to-file copy, make sure to diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go index ff1781d1e..2b8330d4c 100644 --- a/pkg/api/server/register_containers.go +++ b/pkg/api/server/register_containers.go @@ -1176,15 +1176,19 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error { // description: the name or ID of the container // - in: query // name: condition - // type: string - // description: | - // wait until container is to a given condition. default is stopped. valid conditions are: - // - configured - // - created - // - exited - // - paused - // - running - // - stopped + // type: array + // items: + // type: string + // enum: + // - configured + // - created + // - running + // - stopped + // - paused + // - exited + // - removing + // - stopping + // description: "Conditions to wait for. If no condition provided the 'exited' condition is assumed." // produces: // - application/json // responses: diff --git a/pkg/domain/infra/abi/archive.go b/pkg/domain/infra/abi/archive.go index c64dfb02a..f38f5c132 100644 --- a/pkg/domain/infra/abi/archive.go +++ b/pkg/domain/infra/abi/archive.go @@ -3,6 +3,7 @@ package abi import ( "context" "io" + "path/filepath" "strings" buildahCopiah "github.com/containers/buildah/copier" @@ -93,7 +94,7 @@ func (ic *ContainerEngine) ContainerCopyToArchive(ctx context.Context, nameOrID containerPath = "/." } - _, resolvedRoot, resolvedContainerPath, err := ic.containerStat(container, containerMountPoint, containerPath) + statInfo, resolvedRoot, resolvedContainerPath, err := ic.containerStat(container, containerMountPoint, containerPath) if err != nil { unmount() return nil, err @@ -110,8 +111,8 @@ func (ic *ContainerEngine) ContainerCopyToArchive(ctx context.Context, nameOrID return func() error { defer container.Unmount(false) getOptions := buildahCopiah.GetOptions{ - // Unless the specified path ends with ".", we want to copy the base directory. - KeepDirectoryNames: !strings.HasSuffix(resolvedContainerPath, "."), + // Unless the specified points to ".", we want to copy the base directory. + KeepDirectoryNames: statInfo.IsDir && filepath.Base(containerPath) != ".", UIDMap: idMappings.UIDMap, GIDMap: idMappings.GIDMap, ChownDirs: idPair, diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c index 2e1fddc48..d588d848b 100644 --- a/pkg/rootless/rootless_linux.c +++ b/pkg/rootless/rootless_linux.c @@ -196,7 +196,11 @@ can_use_shortcut () return false; if (strstr (argv[0], "podman") == NULL) - return false; + { + free (argv[0]); + free (argv); + return false; + } for (argc = 0; argv[argc]; argc++) { diff --git a/test/e2e/run_memory_test.go b/test/e2e/run_memory_test.go index ad3a2b54f..8371d3cae 100644 --- a/test/e2e/run_memory_test.go +++ b/test/e2e/run_memory_test.go @@ -2,6 +2,7 @@ package integration import ( "os" + "strconv" . "github.com/containers/podman/v2/test/utils" . "github.com/onsi/ginkgo" @@ -90,4 +91,27 @@ var _ = Describe("Podman run memory", func() { Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(Equal("41943040")) }) + + It("podman run kernel-memory test", func() { + if podmanTest.Host.Distribution == "ubuntu" { + Skip("Unable to perform test on Ubuntu distributions due to memory management") + } + var session *PodmanSessionIntegration + if CGROUPSV2 { + session = podmanTest.Podman([]string{"run", "--memory", "256m", "--memory-swap", "-1", ALPINE, "cat", "/sys/fs/cgroup/memory.swap.max"}) + } else { + session = podmanTest.Podman([]string{"run", "--cgroupns=private", ALPINE, "cat", "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes"}) + } + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(BeZero()) + output := session.OutputToString() + Expect(err).To(BeNil()) + if CGROUPSV2 { + Expect(output).To(Equal("max")) + } else { + crazyHighNumber, err := strconv.ParseInt(output, 10, 64) + Expect(err).To(BeZero()) + Expect(crazyHighNumber).To(BeNumerically(">", 936854771712)) + } + }) }) diff --git a/test/system/065-cp.bats b/test/system/065-cp.bats index d3cf1c274..0fcc437d4 100644 --- a/test/system/065-cp.bats +++ b/test/system/065-cp.bats @@ -18,6 +18,8 @@ load helpers echo "${randomcontent[0]}" > $srcdir/hostfile0 echo "${randomcontent[1]}" > $srcdir/hostfile1 echo "${randomcontent[2]}" > $srcdir/hostfile2 + mkdir -p $srcdir/subdir + echo "${randomcontent[2]}" > $srcdir/subdir/dotfile. run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sleep infinity run_podman exec cpcontainer mkdir /srv/subdir @@ -50,6 +52,11 @@ load helpers is "$output" "${randomcontent[$id]}" "$description (cp -> ctr:$dest)" done < <(parse_table "$tests") + # Dots are special for dirs not files. + run_podman cp $srcdir/subdir/dotfile. cpcontainer:/tmp + run_podman exec cpcontainer cat /tmp/dotfile. + is "$output" "${randomcontent[2]}" "$description (cp -> ctr:$dest)" + # Host path does not exist. run_podman 125 cp $srcdir/IdoNotExist cpcontainer:/tmp is "$output" 'Error: ".*/IdoNotExist" could not be found on the host' \ @@ -76,12 +83,14 @@ load helpers ) run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sleep infinity run_podman exec cpcontainer sh -c "echo ${randomcontent[0]} > /tmp/containerfile" + run_podman exec cpcontainer sh -c "echo ${randomcontent[0]} > /tmp/dotfile." run_podman exec cpcontainer sh -c "echo ${randomcontent[1]} > /srv/containerfile1" run_podman exec cpcontainer sh -c "mkdir /srv/subdir; echo ${randomcontent[2]} > /srv/subdir/containerfile2" # format is: <id> | <source arg to cp> | <destination arg (appended to $srcdir) to cp> | <full dest path (appended to $srcdir)> | <test name> tests=" 0 | /tmp/containerfile | | /containerfile | copy to srcdir/ +0 | /tmp/dotfile. | | /dotfile. | copy to srcdir/ 0 | /tmp/containerfile | / | /containerfile | copy to srcdir/ 0 | /tmp/containerfile | /. | /containerfile | copy to srcdir/. 0 | /tmp/containerfile | /newfile | /newfile | copy to srcdir/newfile @@ -117,12 +126,18 @@ load helpers echo "${randomcontent[0]}" > $srcdir/hostfile0 echo "${randomcontent[1]}" > $srcdir/hostfile1 + # "." and "dir/." will copy the contents, so make sure that a dir ending + # with dot is treated correctly. + mkdir -p $srcdir. + cp $srcdir/* $srcdir./ + run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sleep infinity run_podman exec cpcontainer mkdir /srv/subdir # format is: <source arg to cp (appended to srcdir)> | <destination arg to cp> | <full dest path> | <test name> tests=" | / | /dir-test | copy to root + . | / | /dir-test. | copy dotdir to root / | /tmp | /tmp/dir-test | copy to tmp /. | /usr/ | /usr/ | copy contents of dir to usr/ | . | /srv/dir-test | copy to workdir (rel path) @@ -153,6 +168,9 @@ load helpers run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sleep infinity run_podman exec cpcontainer sh -c 'mkdir /srv/subdir; echo "This first file is on the container" > /srv/subdir/containerfile1' run_podman exec cpcontainer sh -c 'echo "This second file is on the container as well" > /srv/subdir/containerfile2' + # "." and "dir/." will copy the contents, so make sure that a dir ending + # with dot is treated correctly. + run_podman exec cpcontainer sh -c 'mkdir /tmp/subdir.; cp /srv/subdir/* /tmp/subdir./' run_podman cp cpcontainer:/srv $srcdir run cat $srcdir/srv/subdir/containerfile1 @@ -174,6 +192,14 @@ load helpers is "$output" "This first file is on the container" run cat $srcdir/containerfile2 is "$output" "This second file is on the container as well" + rm -rf $srcdir/subdir + + run_podman cp cpcontainer:/tmp/subdir. $srcdir + run cat $srcdir/subdir./containerfile1 + is "$output" "This first file is on the container" + run cat $srcdir/subdir./containerfile2 + is "$output" "This second file is on the container as well" + rm -rf $srcdir/subdir. run_podman rm -f cpcontainer } |