github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/test/e2e/cp_test.go (about) 1 package integration 2 3 import ( 4 "io/ioutil" 5 "os" 6 "os/exec" 7 "os/user" 8 "path/filepath" 9 10 . "github.com/hanks177/podman/v4/test/utils" 11 . "github.com/onsi/ginkgo" 12 . "github.com/onsi/gomega" 13 . "github.com/onsi/gomega/gexec" 14 ) 15 16 // NOTE: Only smoke tests. The system tests (i.e., "./test/system/*") take 17 // care of function and regression tests. Please consider adding system tests 18 // rather than e2e tests. System tests are used in RHEL gating. 19 20 var _ = Describe("Podman cp", func() { 21 var ( 22 tempdir string 23 err error 24 podmanTest *PodmanTestIntegration 25 ) 26 27 BeforeEach(func() { 28 tempdir, err = CreateTempDirInTempDir() 29 if err != nil { 30 os.Exit(1) 31 } 32 podmanTest = PodmanTestCreate(tempdir) 33 podmanTest.Setup() 34 }) 35 36 AfterEach(func() { 37 podmanTest.Cleanup() 38 f := CurrentGinkgoTestDescription() 39 processTestResult(f) 40 41 }) 42 43 // Copy a file to the container, then back to the host and make sure 44 // that the contents match. 45 It("podman cp file", func() { 46 srcFile, err := ioutil.TempFile("", "") 47 Expect(err).To(BeNil()) 48 defer srcFile.Close() 49 defer os.Remove(srcFile.Name()) 50 51 originalContent := []byte("podman cp file test") 52 err = ioutil.WriteFile(srcFile.Name(), originalContent, 0644) 53 Expect(err).To(BeNil()) 54 55 // Create a container. NOTE that container mustn't be running for copying. 56 session := podmanTest.Podman([]string{"create", ALPINE}) 57 session.WaitWithDefaultTimeout() 58 Expect(session).Should(Exit(0)) 59 name := session.OutputToString() 60 61 // Copy TO the container. 62 63 // Cannot copy to a nonexistent path (note the trailing "/"). 64 session = podmanTest.Podman([]string{"cp", srcFile.Name(), name + ":foo/"}) 65 session.WaitWithDefaultTimeout() 66 Expect(session).To(ExitWithError()) 67 68 // The file will now be created (and written to). 69 session = podmanTest.Podman([]string{"cp", srcFile.Name(), name + ":foo"}) 70 session.WaitWithDefaultTimeout() 71 Expect(session).Should(Exit(0)) 72 73 // Copy FROM the container. 74 75 destFile, err := ioutil.TempFile("", "") 76 Expect(err).To(BeNil()) 77 defer destFile.Close() 78 defer os.Remove(destFile.Name()) 79 80 session = podmanTest.Podman([]string{"cp", name + ":foo", destFile.Name()}) 81 session.WaitWithDefaultTimeout() 82 Expect(session).Should(Exit(0)) 83 84 session = podmanTest.Podman([]string{"start", name}) 85 session.WaitWithDefaultTimeout() 86 Expect(session).Should(Exit(0)) 87 88 // Now make sure the content matches. 89 roundtripContent, err := ioutil.ReadFile(destFile.Name()) 90 Expect(err).To(BeNil()) 91 Expect(roundtripContent).To(Equal(originalContent)) 92 }) 93 94 // Copy a file to the container, then back to the host in --pid=host 95 It("podman cp --pid=host file", func() { 96 SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1") 97 srcFile, err := ioutil.TempFile("", "") 98 Expect(err).To(BeNil()) 99 defer srcFile.Close() 100 defer os.Remove(srcFile.Name()) 101 102 originalContent := []byte("podman cp file test") 103 err = ioutil.WriteFile(srcFile.Name(), originalContent, 0644) 104 Expect(err).To(BeNil()) 105 106 // Create a container. NOTE that container mustn't be running for copying. 107 session := podmanTest.Podman([]string{"create", "--pid=host", ALPINE, "top"}) 108 session.WaitWithDefaultTimeout() 109 Expect(session).Should(Exit(0)) 110 name := session.OutputToString() 111 112 session = podmanTest.Podman([]string{"start", name}) 113 session.WaitWithDefaultTimeout() 114 Expect(session).Should(Exit(0)) 115 116 // The file will now be created (and written to). 117 session = podmanTest.Podman([]string{"cp", srcFile.Name(), name + ":foo"}) 118 session.WaitWithDefaultTimeout() 119 Expect(session).Should(Exit(0)) 120 121 // Copy FROM the container. 122 123 destFile, err := ioutil.TempFile("", "") 124 Expect(err).To(BeNil()) 125 defer destFile.Close() 126 defer os.Remove(destFile.Name()) 127 128 session = podmanTest.Podman([]string{"cp", name + ":foo", destFile.Name()}) 129 session.WaitWithDefaultTimeout() 130 Expect(session).Should(Exit(0)) 131 132 // Now make sure the content matches. 133 roundtripContent, err := ioutil.ReadFile(destFile.Name()) 134 Expect(err).To(BeNil()) 135 Expect(roundtripContent).To(Equal(originalContent)) 136 }) 137 138 // Create a symlink in the container, use it as a copy destination and 139 // make sure that the link and the resolved path are accessible and 140 // give the right content. 141 It("podman cp symlink", func() { 142 srcFile, err := ioutil.TempFile("", "") 143 Expect(err).To(BeNil()) 144 defer srcFile.Close() 145 defer os.Remove(srcFile.Name()) 146 147 originalContent := []byte("podman cp symlink test") 148 err = ioutil.WriteFile(srcFile.Name(), originalContent, 0644) 149 Expect(err).To(BeNil()) 150 151 session := podmanTest.Podman([]string{"run", "-d", ALPINE, "top"}) 152 session.WaitWithDefaultTimeout() 153 Expect(session).Should(Exit(0)) 154 name := session.OutputToString() 155 156 session = podmanTest.Podman([]string{"exec", name, "ln", "-s", "/tmp", "/test"}) 157 session.WaitWithDefaultTimeout() 158 Expect(session).Should(Exit(0)) 159 160 session = podmanTest.Podman([]string{"cp", "--pause=false", srcFile.Name(), name + ":/test"}) 161 session.WaitWithDefaultTimeout() 162 Expect(session).Should(Exit(0)) 163 164 session = podmanTest.Podman([]string{"exec", name, "cat", "/tmp/" + filepath.Base(srcFile.Name())}) 165 session.WaitWithDefaultTimeout() 166 Expect(session).Should(Exit(0)) 167 Expect(session.OutputToString()).To(ContainSubstring(string(originalContent))) 168 169 session = podmanTest.Podman([]string{"exec", name, "cat", "/test/" + filepath.Base(srcFile.Name())}) 170 session.WaitWithDefaultTimeout() 171 Expect(session).Should(Exit(0)) 172 Expect(session.OutputToString()).To(ContainSubstring(string(originalContent))) 173 }) 174 175 // Copy a file to a volume in the container. The tricky part is that 176 // containers mustn't be running for copying, so Podman has to do some 177 // intense Yoga and 1) detect volume paths on the container, 2) resolve 178 // the path to the volume's mount point on the host, and 3) copy the 179 // data to the volume and not the container. 180 It("podman cp volume", func() { 181 srcFile, err := ioutil.TempFile("", "") 182 Expect(err).To(BeNil()) 183 defer srcFile.Close() 184 defer os.Remove(srcFile.Name()) 185 186 originalContent := []byte("podman cp volume") 187 err = ioutil.WriteFile(srcFile.Name(), originalContent, 0644) 188 Expect(err).To(BeNil()) 189 session := podmanTest.Podman([]string{"volume", "create", "data"}) 190 session.WaitWithDefaultTimeout() 191 Expect(session).Should(Exit(0)) 192 193 session = podmanTest.Podman([]string{"create", "-v", "data:/data", "--name", "container1", ALPINE}) 194 session.WaitWithDefaultTimeout() 195 Expect(session).Should(Exit(0)) 196 197 session = podmanTest.Podman([]string{"cp", srcFile.Name(), "container1" + ":/data/file.txt"}) 198 session.WaitWithDefaultTimeout() 199 Expect(session).Should(Exit(0)) 200 201 // Now get the volume's mount point, read the file and make 202 // sure the contents match. 203 session = podmanTest.Podman([]string{"volume", "inspect", "data", "--format", "{{.Mountpoint}}"}) 204 session.WaitWithDefaultTimeout() 205 Expect(session).Should(Exit(0)) 206 207 volumeMountPoint := session.OutputToString() 208 copiedContent, err := ioutil.ReadFile(filepath.Join(volumeMountPoint, "file.txt")) 209 Expect(err).To(BeNil()) 210 Expect(copiedContent).To(Equal(originalContent)) 211 }) 212 213 // Create another user in the container, let them create a file, copy 214 // it to the host and back to the container and make sure that we can 215 // access it, and (roughly) the right users own it. 216 It("podman cp from ctr chown ", func() { 217 srcFile, err := ioutil.TempFile("", "") 218 Expect(err).To(BeNil()) 219 defer srcFile.Close() 220 defer os.Remove(srcFile.Name()) 221 222 setup := podmanTest.RunTopContainer("testctr") 223 setup.WaitWithDefaultTimeout() 224 Expect(setup).Should(Exit(0)) 225 226 session := podmanTest.Podman([]string{"exec", "testctr", "adduser", "-S", "testuser"}) 227 session.WaitWithDefaultTimeout() 228 Expect(session).Should(Exit(0)) 229 230 session = podmanTest.Podman([]string{"exec", "-u", "testuser", "testctr", "touch", "/tmp/testfile"}) 231 session.WaitWithDefaultTimeout() 232 Expect(session).Should(Exit(0)) 233 234 session = podmanTest.Podman([]string{"cp", "--pause=false", "testctr:/tmp/testfile", srcFile.Name()}) 235 session.WaitWithDefaultTimeout() 236 Expect(session).Should(Exit(0)) 237 238 // owner of the file copied to local machine is not testuser 239 u, err := user.Current() 240 Expect(err).To(BeNil()) 241 cmd := exec.Command("ls", "-l", srcFile.Name()) 242 cmdRet, err := cmd.Output() 243 Expect(err).To(BeNil()) 244 Expect(string(cmdRet)).To(ContainSubstring(u.Username)) 245 246 session = podmanTest.Podman([]string{"cp", "--pause=false", srcFile.Name(), "testctr:testfile2"}) 247 session.WaitWithDefaultTimeout() 248 Expect(session).Should(Exit(0)) 249 250 // owner of the file copied to a container is the root user 251 session = podmanTest.Podman([]string{"exec", "-it", "testctr", "ls", "-l", "testfile2"}) 252 session.WaitWithDefaultTimeout() 253 Expect(session).Should(Exit(0)) 254 Expect(session.OutputToString()).To(ContainSubstring("root")) 255 }) 256 257 // Copy the root dir "/" of a container to the host. 258 It("podman cp the root directory from the ctr to an existing directory on the host ", func() { 259 container := "copyroottohost" 260 session := podmanTest.RunTopContainer(container) 261 session.WaitWithDefaultTimeout() 262 Expect(session).Should(Exit(0)) 263 264 session = podmanTest.Podman([]string{"exec", container, "touch", "/dummy.txt"}) 265 session.WaitWithDefaultTimeout() 266 Expect(session).Should(Exit(0)) 267 268 tmpDir, err := ioutil.TempDir("", "") 269 Expect(err).To(BeNil()) 270 271 session = podmanTest.Podman([]string{"cp", container + ":/", tmpDir}) 272 session.WaitWithDefaultTimeout() 273 Expect(session).Should(Exit(0)) 274 275 cmd := exec.Command("ls", "-la", tmpDir) 276 output, err := cmd.Output() 277 lsOutput := string(output) 278 Expect(err).To(BeNil()) 279 Expect(lsOutput).To(ContainSubstring("dummy.txt")) 280 Expect(lsOutput).To(ContainSubstring("tmp")) 281 Expect(lsOutput).To(ContainSubstring("etc")) 282 Expect(lsOutput).To(ContainSubstring("var")) 283 Expect(lsOutput).To(ContainSubstring("bin")) 284 Expect(lsOutput).To(ContainSubstring("usr")) 285 }) 286 })