diff options
author | Qi Wang <qiwan@redhat.com> | 2019-09-24 11:35:49 -0400 |
---|---|---|
committer | Qi Wang <qiwan@redhat.com> | 2019-09-25 12:48:05 -0400 |
commit | 0144c3796ba3dd0555e35fd2cc3f76bde10a90a0 (patch) | |
tree | 3548d0de8326852e12d965492b2cad7fa131953a | |
parent | f197ebe8519198ea24a0a395ffeb97711a248c27 (diff) | |
download | podman-0144c3796ba3dd0555e35fd2cc3f76bde10a90a0.tar.gz podman-0144c3796ba3dd0555e35fd2cc3f76bde10a90a0.tar.bz2 podman-0144c3796ba3dd0555e35fd2cc3f76bde10a90a0.zip |
fix cp none exists dest path ends with '/'
close #3894
This patch let podman cp return 'no such file or directory' error if DEST_PATH does not exist and ends with / when copying file.
Signed-off-by: Qi Wang <qiwan@redhat.com>
-rw-r--r-- | cmd/podman/cp.go | 4 | ||||
-rw-r--r-- | docs/podman-cp.1.md | 2 | ||||
-rw-r--r-- | test/e2e/cp_test.go | 51 | ||||
-rw-r--r-- | test/system/065-cp.bats | 13 |
4 files changed, 46 insertions, 24 deletions
diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go index 7205f9357..75a23afd6 100644 --- a/cmd/podman/cp.go +++ b/cmd/podman/cp.go @@ -290,7 +290,7 @@ func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, ch } destdir := destPath - if !srcfi.IsDir() && !strings.HasSuffix(dest, string(os.PathSeparator)) { + if !srcfi.IsDir() { destdir = filepath.Dir(destPath) } _, err = os.Stat(destdir) @@ -329,7 +329,7 @@ func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, ch destfi, err := os.Stat(destPath) if err != nil { - if !os.IsNotExist(err) { + if !os.IsNotExist(err) || strings.HasSuffix(dest, string(os.PathSeparator)) { return errors.Wrapf(err, "failed to get stat of dest path %s", destPath) } } diff --git a/docs/podman-cp.1.md b/docs/podman-cp.1.md index 736bdb12a..0f54b2e8b 100644 --- a/docs/podman-cp.1.md +++ b/docs/podman-cp.1.md @@ -29,7 +29,7 @@ Assuming a path separator of /, a first argument of **src_path** and second argu - **dest_path** does not exist - the file is saved to a file created at **dest_path** - **dest_path** does not exist and ends with / - - **dest_path** is created as a directory and the file is copied into this directory using the basename from **src_path** + - Error condition: the destination directory must exist. - **dest_path** exists and is a file - the destination is overwritten with the source file's contents - **dest_path** exists and is a directory diff --git a/test/e2e/cp_test.go b/test/e2e/cp_test.go index 9b0cb757d..3317683de 100644 --- a/test/e2e/cp_test.go +++ b/test/e2e/cp_test.go @@ -51,6 +51,10 @@ var _ = Describe("Podman cp", func() { err := ioutil.WriteFile(srcPath, fromHostToContainer, 0644) Expect(err).To(BeNil()) + session = podmanTest.Podman([]string{"cp", srcPath, name + ":foo/"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Not(Equal(0))) + session = podmanTest.Podman([]string{"cp", srcPath, name + ":foo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -65,30 +69,29 @@ var _ = Describe("Podman cp", func() { }) It("podman cp file to dir", func() { - srcPath := filepath.Join(podmanTest.RunRoot, "cp_test.txt") - dstDir := filepath.Join(podmanTest.RunRoot, "receive") + name := "testctr" + setup := podmanTest.RunTopContainer(name) + setup.WaitWithDefaultTimeout() + Expect(setup.ExitCode()).To(Equal(0)) + + srcPath := "/tmp/cp_test.txt" fromHostToContainer := []byte("copy from host to container directory") + err := ioutil.WriteFile(srcPath, fromHostToContainer, 0644) + Expect(err).To(BeNil()) - session := podmanTest.Podman([]string{"create", ALPINE, "ls", "foodir/"}) + session := podmanTest.Podman([]string{"exec", name, "mkdir", "foodir"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - name := session.OutputToString() - - err := ioutil.WriteFile(srcPath, fromHostToContainer, 0644) - Expect(err).To(BeNil()) - err = os.Mkdir(dstDir, 0755) - Expect(err).To(BeNil()) session = podmanTest.Podman([]string{"cp", srcPath, name + ":foodir/"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"cp", name + ":foodir/cp_test.txt", dstDir}) + session = podmanTest.Podman([]string{"exec", name, "ls", "foodir/cp_test.txt"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - os.Remove("cp_test.txt") - os.RemoveAll("receive") + os.Remove("/tmp/cp_test.txt") }) It("podman cp dir to dir", func() { @@ -137,10 +140,18 @@ var _ = Describe("Podman cp", func() { session = podmanTest.Podman([]string{"cp", name + ":/foo.tar.gz", "-"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) + + os.RemoveAll(testDirPath) + os.Remove("file.tar.gz") }) It("podman cp tar", func() { - session := podmanTest.Podman([]string{"create", "--name", "testctr", ALPINE, "ls", "-l", "foo"}) + testctr := "testctr" + setup := podmanTest.RunTopContainer(testctr) + setup.WaitWithDefaultTimeout() + Expect(setup.ExitCode()).To(Equal(0)) + + session := podmanTest.Podman([]string{"exec", testctr, "mkdir", "foo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -157,7 +168,7 @@ var _ = Describe("Podman cp", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"start", "-a", "testctr"}) + session = podmanTest.Podman([]string{"exec", testctr, "ls", "-l", "foo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring("file.tar")) @@ -187,6 +198,15 @@ var _ = Describe("Podman cp", func() { _, err = os.Stat("/tmp/cp_test.txt") Expect(err).To(Not(BeNil())) + + session = podmanTest.Podman([]string{"exec", name, "ln", "-s", "/tmp/nonesuch", "/test1"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"cp", "--pause=false", srcPath, name + ":/test1/"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Not(Equal(0))) + }) It("podman cp volume", func() { session := podmanTest.Podman([]string{"volume", "create", "data"}) @@ -208,6 +228,9 @@ var _ = Describe("Podman cp", func() { session = podmanTest.Podman([]string{"cp", "container1" + ":/data/cp_vol1", "cp_vol2"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) + + os.Remove("cp_vol") + os.Remove("cp_vol2") }) It("podman cp from ctr chown ", func() { diff --git a/test/system/065-cp.bats b/test/system/065-cp.bats index 0ca730a50..38660a13c 100644 --- a/test/system/065-cp.bats +++ b/test/system/065-cp.bats @@ -144,12 +144,13 @@ load helpers trap 'exit 0' 15;while :;do sleep 0.5;done" # Copy file from host into container, into a file named 'x' - # Note that the second has a trailing slash; this will trigger mkdir + # Note that the second has a trailing slash, implying a directory. + # Since that destination directory doesn't exist, the cp will fail run_podman cp --pause=false $srcdir/$rand_filename1 cpcontainer:/tmp/d1/x is "$output" "" "output from podman cp 1" - run_podman cp --pause=false $srcdir/$rand_filename2 cpcontainer:/tmp/d2/x/ - is "$output" "" "output from podman cp 3" + run_podman 125 cp --pause=false $srcdir/$rand_filename2 cpcontainer:/tmp/d2/x/ + is "$output" "Error: failed to get stat of dest path .*stat.* no such file or directory" "cp will not create nonexistent destination directory" run_podman cp --pause=false $srcdir/$rand_filename3 cpcontainer:/tmp/d3/x is "$output" "" "output from podman cp 3" @@ -161,10 +162,8 @@ load helpers run_podman exec cpcontainer cat /tmp/nonesuch1 is "$output" "$rand_content1" "cp creates destination file" - # In the second case, podman creates a directory nonesuch2, then - # creates a file with the same name as the input file. THIS IS WEIRD! - run_podman exec cpcontainer cat /tmp/nonesuch2/$rand_filename2 - is "$output" "$rand_content2" "cp creates destination dir and file" + # cp into nonexistent directory should not mkdir nonesuch2 directory + run_podman 1 exec cpcontainer test -e /tmp/nonesuch2 # In the third case, podman (correctly imo) creates a file named 'x' run_podman exec cpcontainer cat /tmp/d3/x |