github.com/containers/podman/v5@v5.1.0-rc1/test/system/065-cp.bats (about) 1 #!/usr/bin/env bats -*- bats -*- 2 # 3 # Tests for 'podman cp' 4 # 5 # ASSUMPTION FOR ALL THESE TESTS: /tmp in the container starts off empty 6 # 7 8 load helpers 9 10 @test "podman cp file from host to container" { 11 srcdir=$PODMAN_TMPDIR/cp-test-file-host-to-ctr 12 mkdir -p $srcdir 13 local -a randomcontent=( 14 random-0-$(random_string 10) 15 random-1-$(random_string 15) 16 random-2-$(random_string 20) 17 ) 18 19 echo "${randomcontent[0]}" > $srcdir/hostfile0 20 echo "${randomcontent[1]}" > $srcdir/hostfile1 21 echo "${randomcontent[2]}" > $srcdir/hostfile2 22 mkdir -p $srcdir/subdir 23 echo "${randomcontent[2]}" > $srcdir/subdir/dotfile. 24 25 run_podman run -d --name destrunning --workdir=/srv $IMAGE sh -c "mkdir /srv/subdir; echo READY; sleep infinity" 26 wait_for_ready destrunning 27 28 # Commit the image for testing non-running containers 29 run_podman commit -q destrunning 30 cpimage="$output" 31 32 # format is: <id> | <destination arg to cp> | <full dest path> | <test name> 33 # where: 34 # id is 0-2, one of the random strings/files 35 # dest arg is the right-hand argument to 'podman cp' (may be implicit) 36 # dest path is the full explicit path we expect to see 37 # test name is a short description of what we're testing here 38 tests=" 39 0 | / | /hostfile0 | copy to root 40 0 | /anotherbase.txt | /anotherbase.txt | copy to root, new name 41 0 | /tmp | /tmp/hostfile0 | copy to /tmp 42 1 | /tmp/ | /tmp/hostfile1 | copy to /tmp/ 43 2 | /tmp/. | /tmp/hostfile2 | copy to /tmp/. 44 0 | /tmp/anotherbase.txt | /tmp/anotherbase.txt | copy to /tmp, new name 45 0 | . | /srv/hostfile0 | copy to workdir (rel path), new name 46 1 | ./ | /srv/hostfile1 | copy to workdir (rel path), new name 47 0 | anotherbase.txt | /srv/anotherbase.txt | copy to workdir (rel path), new name 48 0 | subdir | /srv/subdir/hostfile0 | copy to workdir/subdir 49 " 50 51 defer-assertion-failures 52 53 # RUNNING container 54 while read id dest dest_fullname description; do 55 run_podman cp $srcdir/hostfile$id destrunning:$dest 56 run_podman exec destrunning cat $dest_fullname 57 is "$output" "${randomcontent[$id]}" "$description (cp -> ctr:$dest)" 58 done < <(parse_table "$tests") 59 60 # Dots are special for dirs not files. 61 run_podman cp $srcdir/subdir/dotfile. destrunning:/tmp 62 run_podman exec destrunning cat /tmp/dotfile. 63 is "$output" "${randomcontent[2]}" "$description (cp -> ctr:$dest)" 64 65 # Host path does not exist. 66 run_podman 125 cp $srcdir/IdoNotExist destrunning:/tmp 67 is "$output" 'Error: ".*/IdoNotExist" could not be found on the host' \ 68 "copy nonexistent host path" 69 70 # Container (parent) path does not exist. 71 run_podman 125 cp $srcdir/hostfile0 destrunning:/IdoNotExist/ 72 is "$output" 'Error: "/IdoNotExist/" could not be found on container destrunning: no such file or directory' \ 73 "copy into nonexistent path in container" 74 75 run_podman rm -t 0 -f destrunning 76 77 # CREATED container 78 while read id dest dest_fullname description; do 79 run_podman create --name destcreated --workdir=/srv $cpimage sleep infinity 80 run_podman cp $srcdir/hostfile$id destcreated:$dest 81 run_podman start destcreated 82 run_podman exec destcreated cat $dest_fullname 83 is "$output" "${randomcontent[$id]}" "$description (cp -> ctr:$dest)" 84 run_podman rm -t 0 -f destcreated 85 done < <(parse_table "$tests") 86 87 run_podman rmi -f $cpimage 88 } 89 90 91 @test "podman cp file from host to container tmpfs mount" { 92 srcdir=$PODMAN_TMPDIR/cp-test-file-host-to-ctr 93 mkdir -p $srcdir 94 content=tmpfile-content$(random_string 20) 95 echo $content > $srcdir/file 96 97 # RUNNING container 98 run_podman run -d --mount type=tmpfs,dst=/tmp --name destrunning $IMAGE sleep infinity 99 run_podman cp $srcdir/file destrunning:/tmp 100 run_podman exec destrunning cat /tmp/file 101 is "$output" "${content}" "cp to running container's tmpfs" 102 run_podman rm -t 0 -f destrunning 103 104 # CREATED container (with copy up) 105 run_podman create --mount type=tmpfs,dst=/tmp --name destcreated $IMAGE sleep infinity 106 run_podman cp $srcdir/file destcreated:/tmp 107 run_podman start destcreated 108 run_podman exec destcreated cat /tmp/file 109 is "$output" "${content}" "cp to created container's tmpfs" 110 run_podman rm -t 0 -f destcreated 111 } 112 113 114 @test "podman cp (-a=true) file from host to container and check ownership" { 115 srcdir=$PODMAN_TMPDIR/cp-test-file-host-to-ctr 116 mkdir -p $srcdir 117 content=cp-user-test-$(random_string 10) 118 echo "content" > $srcdir/hostfile 119 userid=$(id -u) 120 121 keepid="--userns=keep-id" 122 is_rootless || keepid="" 123 run_podman run --user=$userid ${keepid} -d --name destrunning $IMAGE sleep infinity 124 run_podman cp $srcdir/hostfile destrunning:/tmp/hostfile 125 run_podman exec destrunning stat -c "%u" /tmp/hostfile 126 is "$output" "$userid" "copied file is chowned to the container user" 127 run_podman rm -t 0 -f destrunning 128 } 129 130 @test "podman cp (-a=false) file from host to container and check ownership" { 131 local tmpdir="${PODMAN_TMPDIR}/cp-test-file-host-to-ctr" 132 mkdir -p "${tmpdir}" 133 134 pushd "${tmpdir}" 135 touch a.txt 136 tar --owner=1042 --group=1043 -cf a.tar a.txt 137 popd 138 139 userid=$(id -u) 140 141 keepid="--userns=keep-id" 142 is_rootless || keepid="" 143 run_podman run --user=$userid ${keepid} -d --name destrunning $IMAGE sleep infinity 144 run_podman cp -a=false - destrunning:/tmp/ < "${tmpdir}/a.tar" 145 run_podman exec destrunning stat -c "%u:%g" /tmp/a.txt 146 is "$output" "1042:1043" "copied file retains uid/gid from the tar" 147 run_podman rm -t 0 -f destrunning 148 } 149 150 151 @test "podman cp file from/to host while --pid=host" { 152 if is_rootless && ! is_cgroupsv2; then 153 skip "'podman cp --pid=host' (rootless) only works with cgroups v2" 154 fi 155 156 srcdir=$PODMAN_TMPDIR/cp-pid-equals-host 157 mkdir -p $srcdir 158 touch $srcdir/hostfile 159 160 run_podman run --pid=host -d --name cpcontainer $IMAGE sleep infinity 161 run_podman cp $srcdir/hostfile cpcontainer:/tmp/hostfile 162 run_podman cp cpcontainer:/tmp/hostfile $srcdir/hostfile1 163 run_podman rm -t 0 -f cpcontainer 164 } 165 166 @test "podman cp file from container to host" { 167 srcdir=$PODMAN_TMPDIR/cp-test-file-ctr-to-host 168 mkdir -p $srcdir 169 170 # Create 3 files with random content in the container. 171 local -a randomcontent=( 172 random-0-$(random_string 10) 173 random-1-$(random_string 15) 174 random-2-$(random_string 20) 175 ) 176 run_podman run -d --name srcrunning --workdir=/srv $IMAGE sh -c "mkdir /srv/subdir; 177 echo ${randomcontent[0]} > /tmp/containerfile; 178 echo ${randomcontent[0]} > /tmp/dotfile.; 179 echo ${randomcontent[1]} > /srv/containerfile1; 180 echo ${randomcontent[2]} > /srv/subdir/containerfile2; 181 echo READY; 182 sleep infinity" 183 wait_for_ready srcrunning 184 185 # Commit the image for testing non-running containers 186 run_podman commit -q srcrunning 187 cpimage="$output" 188 189 # format is: <id> | <source arg to cp> | <destination arg (appended to $srcdir) to cp> | <full dest path (appended to $srcdir)> | <test name> 190 tests=" 191 0 | /tmp/containerfile | | /containerfile | copy to srcdir/ 192 0 | /tmp/dotfile. | | /dotfile. | copy to srcdir/ 193 0 | /tmp/containerfile | / | /containerfile | copy to srcdir/ 194 0 | /tmp/containerfile | /. | /containerfile | copy to srcdir/. 195 0 | /tmp/containerfile | /newfile | /newfile | copy to srcdir/newfile 196 1 | containerfile1 | / | /containerfile1 | copy from workdir (rel path) to srcdir 197 2 | subdir/containerfile2 | / | /containerfile2 | copy from workdir/subdir (rel path) to srcdir 198 " 199 200 defer-assertion-failures 201 202 # RUNNING container 203 while read id src dest dest_fullname description; do 204 # dest may be "''" for empty table cells 205 if [[ $dest == "''" ]];then 206 unset dest 207 fi 208 run_podman cp srcrunning:$src "$srcdir$dest" 209 is "$(< $srcdir$dest_fullname)" "${randomcontent[$id]}" "$description (cp ctr:$src to \$srcdir$dest)" 210 rm $srcdir$dest_fullname 211 done < <(parse_table "$tests") 212 run_podman rm -t 0 -f srcrunning 213 214 # Created container 215 run_podman create --name srccreated --workdir=/srv $cpimage 216 while read id src dest dest_fullname description; do 217 # dest may be "''" for empty table cells 218 if [[ $dest == "''" ]];then 219 unset dest 220 fi 221 run_podman cp srccreated:$src "$srcdir$dest" 222 is "$(< $srcdir$dest_fullname)" "${randomcontent[$id]}" "$description (cp ctr:$src to \$srcdir$dest)" 223 rm $srcdir$dest_fullname 224 done < <(parse_table "$tests") 225 run_podman rm -t 0 -f srccreated 226 227 run_podman rmi -f $cpimage 228 } 229 230 231 @test "podman cp file from container to container" { 232 # Create 3 files with random content in the container. 233 local -a randomcontent=( 234 random-0-$(random_string 10) 235 random-1-$(random_string 15) 236 random-2-$(random_string 20) 237 ) 238 239 run_podman run -d --name srcrunning --workdir=/srv $IMAGE sh -c "mkdir /srv/subdir; 240 echo ${randomcontent[0]} > /tmp/containerfile; 241 echo ${randomcontent[0]} > /tmp/dotfile.; 242 echo ${randomcontent[1]} > /srv/containerfile1; 243 echo ${randomcontent[2]} > /srv/subdir/containerfile2; 244 echo READY; 245 sleep infinity" 246 wait_for_ready srcrunning 247 248 # Commit the image for testing non-running containers 249 run_podman commit -q srcrunning 250 cpimage="$output" 251 252 # format is: <id> | <source arg to cp> | <destination arg (appended to $srcdir) to cp> | <full dest path (appended to $srcdir)> | <test name> 253 tests=" 254 0 | /tmp/containerfile | / | /containerfile | / 255 0 | /tmp/dotfile. | / | /dotfile. | / 256 0 | /tmp/containerfile | / | /containerfile | / 257 0 | /tmp/containerfile | /. | /containerfile | /. 258 0 | /tmp/containerfile | /newfile | /newfile | /newfile 259 1 | containerfile1 | / | /containerfile1 | copy from workdir (rel path) to / 260 2 | subdir/containerfile2 | / | /containerfile2 | copy from workdir/subdir (rel path) to / 261 " 262 263 defer-assertion-failures 264 265 # From RUNNING container 266 local -a destcontainers=() 267 while read id src dest dest_fullname description; do 268 # dest may be "''" for empty table cells 269 if [[ $dest == "''" ]];then 270 unset dest 271 fi 272 273 # To RUNNING container 274 run_podman run -d $IMAGE sleep infinity 275 destcontainer="$output" 276 destcontainers+=($destcontainer) 277 run_podman cp srcrunning:$src $destcontainer:"$dest" 278 run_podman exec $destcontainer cat "$dest_fullname" 279 is "$output" "${randomcontent[$id]}" "$description (cp ctr:$src to $dest - RUNNING)" 280 281 # To CREATED container 282 run_podman create $IMAGE sleep infinity 283 destcontainer="$output" 284 destcontainers+=($destcontainer) 285 run_podman cp srcrunning:$src $destcontainer:"$dest" 286 run_podman start $destcontainer 287 run_podman exec $destcontainer cat "$dest_fullname" 288 is "$output" "${randomcontent[$id]}" "$description (cp ctr:$src to $dest - CREATED)" 289 done < <(parse_table "$tests") 290 run_podman rm -t 0 -f srcrunning ${destcontainers[@]} 291 292 # From CREATED container 293 destcontainers=() 294 run_podman create --name srccreated --workdir=/srv $cpimage 295 while read id src dest dest_fullname description; do 296 # dest may be "''" for empty table cells 297 if [[ $dest == "''" ]];then 298 unset dest 299 fi 300 301 # To RUNNING container 302 run_podman run -d $IMAGE sleep infinity 303 destcontainer="$output" 304 destcontainers+=($destcontainer) 305 run_podman cp srccreated:$src $destcontainer:"$dest" 306 run_podman exec $destcontainer cat "$dest_fullname" 307 is "$output" "${randomcontent[$id]}" "$description (cp ctr:$src to $dest)" 308 # To CREATED container 309 run_podman create $IMAGE sleep infinity 310 destcontainer="$output" 311 destcontainers+=($destcontainer) 312 run_podman cp srccreated:$src $destcontainer:"$dest" 313 run_podman start $destcontainer 314 run_podman exec $destcontainer cat "$dest_fullname" 315 is "$output" "${randomcontent[$id]}" "$description (cp ctr:$src to $dest)" 316 done < <(parse_table "$tests") 317 run_podman rm -t 0 -f srccreated ${destcontainers[@]} 318 run_podman rmi -f $cpimage 319 } 320 321 322 @test "podman cp dir from host to container" { 323 srcdir=$PODMAN_TMPDIR 324 mkdir -p $srcdir/dir/sub 325 local -a randomcontent=( 326 random-0-$(random_string 10) 327 random-1-$(random_string 15) 328 ) 329 echo "${randomcontent[0]}" > $srcdir/dir/sub/hostfile0 330 echo "${randomcontent[1]}" > $srcdir/dir/sub/hostfile1 331 332 # "." and "dir/." will copy the contents, so make sure that a dir ending 333 # with dot is treated correctly. 334 mkdir -p $srcdir/dir. 335 cp -r $srcdir/dir/* $srcdir/dir. 336 337 run_podman run -d --name destrunning --workdir=/srv $IMAGE sh -c "mkdir /srv/subdir; echo READY;sleep infinity" 338 wait_for_ready destrunning 339 340 # Commit the image for testing non-running containers 341 run_podman commit -q destrunning 342 cpimage="$output" 343 344 # format is: <source arg to cp (appended to srcdir)> | <destination arg to cp> | <full dest path> | <test name> 345 tests=" 346 dir | / | /dir/sub | copy dir to root 347 dir. | / | /dir./sub | copy dir. to root 348 dir/ | /tmp | /tmp/dir/sub | copy dir/ to tmp 349 dir/. | /usr/ | /usr/sub | copy dir/. usr/ 350 dir/sub | . | /srv/sub | copy dir/sub to workdir (rel path) 351 dir/sub/. | subdir/. | /srv/subdir | copy dir/sub/. to workdir subdir (rel path) 352 dir | /newdir1 | /newdir1/sub | copy dir to newdir1 353 dir/ | /newdir2 | /newdir2/sub | copy dir/ to newdir2 354 dir/. | /newdir3 | /newdir3/sub | copy dir/. to newdir3 355 " 356 357 defer-assertion-failures 358 359 # RUNNING container 360 while read src dest dest_fullname description; do 361 run_podman cp $srcdir/$src destrunning:$dest 362 run_podman exec destrunning cat $dest_fullname/hostfile0 $dest_fullname/hostfile1 363 is "$(echo $output)" "${randomcontent[*]}" "$description (cp -> ctr:$dest - RUNNING)" 364 done < <(parse_table "$tests") 365 run_podman rm -t 0 -f destrunning 366 367 # CREATED container 368 while read src dest dest_fullname description; do 369 run_podman create --name destcreated --workdir=/srv $cpimage sleep infinity 370 run_podman cp $srcdir/$src destcreated:$dest 371 run_podman start destcreated 372 run_podman exec destcreated cat $dest_fullname/hostfile0 $dest_fullname/hostfile1 373 is "$(echo $output)" "${randomcontent[*]}" "$description (cp -> ctr:$dest - CREATED)" 374 run_podman rm -t 0 -f destcreated 375 done < <(parse_table "$tests") 376 377 run_podman create --name destnotdir --workdir=/srv $cpimage sleep infinity 378 run_podman 125 cp $srcdir destnotdir:/etc/os-release 379 is "$output" "Error: destination must be a directory when copying a directory" "cannot copy directory to file" 380 run_podman rm -t 0 -f destnotdir 381 382 run_podman rmi -f $cpimage 383 } 384 385 386 @test "podman cp dir from container to host" { 387 destdir=$PODMAN_TMPDIR/cp-test-dir-ctr-to-host 388 mkdir -p $destdir 389 390 # Create 2 files with random content in the container. 391 local -a randomcontent=( 392 random-0-$(random_string 10) 393 random-1-$(random_string 15) 394 ) 395 396 run_podman run -d --name srcrunning --workdir=/srv $IMAGE sh -c "mkdir /srv/subdir; 397 echo ${randomcontent[0]} > /srv/subdir/containerfile0; \ 398 echo ${randomcontent[1]} > /srv/subdir/containerfile1; \ 399 mkdir /tmp/subdir.; cp /srv/subdir/* /tmp/subdir./; \ 400 echo READY; 401 sleep infinity" 402 wait_for_ready srcrunning 403 404 # Commit the image for testing non-running containers 405 run_podman commit -q srcrunning 406 cpimage="$output" 407 408 # format is: <source arg to cp (appended to /srv)> | <dest> | <full dest path> | <test name> 409 tests=" 410 /srv | | /srv/subdir | copy /srv 411 /srv | /newdir | /newdir/subdir | copy /srv to /newdir 412 /srv/ | | /srv/subdir | copy /srv/ 413 /srv/. | | /subdir | copy /srv/. 414 /srv/. | /newdir | /newdir/subdir | copy /srv/. to /newdir 415 /srv/subdir/. | | | copy /srv/subdir/. 416 /tmp/subdir. | | /subdir. | copy /tmp/subdir. 417 " 418 419 defer-assertion-failures 420 421 # RUNNING container 422 while read src dest dest_fullname description; do 423 if [[ $dest == "''" ]];then 424 unset dest 425 fi 426 if [[ $dest_fullname == "''" ]];then 427 unset dest_fullname 428 fi 429 run_podman cp srcrunning:$src $destdir$dest 430 is "$(< $destdir$dest_fullname/containerfile0)" "${randomcontent[0]}" "$description RUNNING (containerfile0)" 431 is "$(< $destdir$dest_fullname/containerfile1)" "${randomcontent[1]}" "$description RUNNING (containerfile1)" 432 rm -rf ${destdir:?}/* 433 done < <(parse_table "$tests") 434 run_podman rm -t 0 -f srcrunning 435 436 # CREATED container 437 run_podman create --name srccreated --workdir=/srv $cpimage 438 while read src dest dest_fullname description; do 439 if [[ $dest == "''" ]];then 440 unset dest 441 fi 442 if [[ $dest_fullname == "''" ]];then 443 unset dest_fullname 444 fi 445 run_podman cp srccreated:$src $destdir$dest 446 is "$(< $destdir$dest_fullname/containerfile0)" "${randomcontent[0]}" "$description CREATED (containerfile0)" 447 is "$(< $destdir$dest_fullname/containerfile1)" "${randomcontent[1]}" "$description CREATED (containerfile1)" 448 rm -rf ${destdir:?}/* 449 done < <(parse_table "$tests") 450 451 touch $destdir/testfile 452 run_podman 125 cp srccreated:/etc/ $destdir/testfile 453 is "$output" "Error: destination must be a directory when copying a directory" "cannot copy directory to file" 454 run_podman rm -t 0 -f srccreated 455 456 run_podman rmi -f $cpimage 457 } 458 459 460 @test "podman cp dir from container to container" { 461 # Create 2 files with random content in the container. 462 local -a randomcontent=( 463 random-0-$(random_string 10) 464 random-1-$(random_string 15) 465 ) 466 467 run_podman run -d --name srcrunning --workdir=/srv $IMAGE sh -c "mkdir /srv/subdir; 468 echo ${randomcontent[0]} > /srv/subdir/containerfile0; \ 469 echo ${randomcontent[1]} > /srv/subdir/containerfile1; \ 470 mkdir /tmp/subdir.; cp /srv/subdir/* /tmp/subdir./; \ 471 echo READY; 472 sleep infinity" 473 wait_for_ready srcrunning 474 475 # Commit the image for testing non-running containers 476 run_podman commit -q srcrunning 477 cpimage="$output" 478 479 # format is: <source arg to cp (appended to /srv)> | <dest> | <full dest path> | <test name> 480 tests=" 481 /srv | / | /srv/subdir | copy /srv 482 /srv | /newdir | /newdir/subdir | copy /srv to /newdir 483 /srv/ | / | /srv/subdir | copy /srv/ 484 /srv/. | / | /subdir | copy /srv/. 485 /srv/. | /newdir | /newdir/subdir | copy /srv/. to /newdir 486 /srv/subdir/. | / | | copy /srv/subdir/. 487 /tmp/subdir. | / | /subdir. | copy /tmp/subdir. 488 " 489 490 defer-assertion-failures 491 492 # From RUNNING container 493 local -a destcontainers=() 494 while read src dest dest_fullname description; do 495 if [[ $dest_fullname == "''" ]];then 496 unset dest_fullname 497 fi 498 499 # To RUNNING container 500 run_podman run -d $IMAGE sleep infinity 501 destcontainer="$output" 502 destcontainers+=($destcontainer) 503 run_podman cp srcrunning:$src $destcontainer:"$dest" 504 run_podman exec $destcontainer cat "$dest_fullname/containerfile0" "$dest_fullname/containerfile1" 505 is "$(echo $output)" "${randomcontent[*]}" "$description - from RUNNING to RUNNING" 506 507 # To CREATED container 508 run_podman create $IMAGE sleep infinity 509 destcontainer="$output" 510 destcontainers+=($destcontainer) 511 run_podman cp srcrunning:$src $destcontainer:"$dest" 512 run_podman start $destcontainer 513 run_podman exec $destcontainer cat "$dest_fullname/containerfile0" "$dest_fullname/containerfile1" 514 is "$(echo $output)" "${randomcontent[*]}" "$description - from RUNNING to CREATED/STARTED" 515 done < <(parse_table "$tests") 516 run_podman rm -t 0 -f srcrunning ${destcontainers[@]} 517 518 # From CREATED container 519 destcontainers=() 520 run_podman create --name srccreated --workdir=/srv $cpimage 521 while read src dest dest_fullname description; do 522 if [[ $dest_fullname == "''" ]];then 523 unset dest_fullname 524 fi 525 526 # To RUNNING container 527 run_podman run -d $IMAGE sleep infinity 528 destcontainer="$output" 529 destcontainers+=($destcontainer) 530 run_podman cp srccreated:$src $destcontainer:"$dest" 531 run_podman exec $destcontainer cat "$dest_fullname/containerfile0" "$dest_fullname/containerfile1" 532 is "$(echo $output)" "${randomcontent[*]}" "$description - from CREATED to RUNNING" 533 534 # To CREATED container 535 run_podman create $IMAGE sleep infinity 536 destcontainer="$output" 537 destcontainers+=($destcontainer) 538 run_podman start $destcontainer 539 run_podman cp srccreated:$src $destcontainer:"$dest" 540 run_podman exec $destcontainer cat "$dest_fullname/containerfile0" "$dest_fullname/containerfile1" 541 is "$(echo $output)" "${randomcontent[*]}" "$description - from CREATED to CREATED" 542 done < <(parse_table "$tests") 543 544 run_podman rm -t 0 -f srccreated ${destcontainers[@]} 545 run_podman rmi -f $cpimage 546 } 547 548 549 @test "podman cp symlinked directory from container" { 550 destdir=$PODMAN_TMPDIR/cp-weird-symlink 551 mkdir -p $destdir 552 553 # Create 3 files with random content in the container. 554 local -a randomcontent=( 555 random-0-$(random_string 10) 556 random-1-$(random_string 15) 557 ) 558 559 run_podman run -d --name srcrunning $IMAGE sh -c "echo ${randomcontent[0]} > /tmp/containerfile0; \ 560 echo ${randomcontent[1]} > /tmp/containerfile1; \ 561 mkdir /tmp/sub && cd /tmp/sub && ln -s .. weirdlink; \ 562 echo READY; 563 sleep infinity" 564 wait_for_ready srcrunning 565 566 # Commit the image for testing non-running containers 567 run_podman commit -q srcrunning 568 cpimage="$output" 569 570 # RUNNING container 571 # NOTE: /dest does not exist yet but is expected to be created during copy 572 run_podman cp srcrunning:/tmp/sub/weirdlink $destdir/dest 573 for i in 0 1; do 574 assert "$(< $destdir/dest/containerfile$i)" = "${randomcontent[$i]}" \ 575 "eval symlink - running container - file $i/1" 576 done 577 578 run_podman rm -t 0 -f srcrunning 579 rm -rf $srcdir/dest 580 581 # CREATED container 582 run_podman create --name srccreated $cpimage 583 run_podman cp srccreated:/tmp/sub/weirdlink $destdir/dest 584 for i in 0 1; do 585 assert "$(< $destdir/dest/containerfile$i)" = "${randomcontent[$i]}" \ 586 "eval symlink - created container - file $i/1" 587 done 588 run_podman rm -t 0 -f srccreated 589 run_podman rmi $cpimage 590 } 591 592 593 @test "podman cp file from host to container volume" { 594 srcdir=$PODMAN_TMPDIR/cp-test-volume 595 mkdir -p $srcdir 596 echo "This file should be in volume2" > $srcdir/hostfile 597 volume1=$(random_string 20) 598 volume2=$(random_string 20) 599 600 run_podman volume create $volume1 601 run_podman volume inspect $volume1 --format "{{.Mountpoint}}" 602 volume1_mount="$output" 603 run_podman volume create $volume2 604 run_podman volume inspect $volume2 --format "{{.Mountpoint}}" 605 volume2_mount="$output" 606 607 # Create a container using the volume. Note that copying on not-running 608 # containers is allowed, so Podman has to analyze the container paths and 609 # check if they are hitting a volume, and eventually resolve to the path on 610 # the *host*. 611 # This test is extra tricky, as volume2 is mounted into a sub-directory of 612 # volume1. Podman must copy the file into volume2 and not volume1. 613 run_podman create --name cpcontainer -v $volume1:/tmp/volume -v $volume2:/tmp/volume/sub-volume $IMAGE 614 615 run_podman cp $srcdir/hostfile cpcontainer:/tmp/volume/sub-volume 616 is "$(< $volume2_mount/hostfile)" "This file should be in volume2" 617 618 # Volume 1 must be empty. 619 run ls $volume1_mount 620 is "$output" "" 621 622 run_podman rm -t 0 -f cpcontainer 623 run_podman volume rm $volume1 $volume2 624 } 625 626 627 @test "podman cp file from host to container mount" { 628 srcdir=$PODMAN_TMPDIR/cp-test-mount-src 629 mountdir=$PODMAN_TMPDIR/cp-test-mount 630 mkdir -p $srcdir $mountdir 631 echo "This file should be in the mount" > $srcdir/hostfile 632 633 volume=$(random_string 20) 634 run_podman volume create $volume 635 636 # Make it a bit more complex and put the mount on a volume. 637 run_podman create --name cpcontainer -v $volume:/tmp/volume -v $mountdir:/tmp/volume/mount $IMAGE 638 639 run_podman cp $srcdir/hostfile cpcontainer:/tmp/volume/mount 640 is "$(< $mountdir/hostfile)" "This file should be in the mount" 641 642 run_podman rm -t 0 -f cpcontainer 643 run_podman volume rm $volume 644 } 645 646 647 # Create two random-name random-content files in /tmp in the container 648 # podman-cp them into the host using '/tmp/*', i.e. asking podman to 649 # perform wildcard expansion in the container. We should get both 650 # files copied into the host. 651 @test "podman cp * - wildcard copy multiple files from container to host" { 652 srcdir=$PODMAN_TMPDIR/cp-test-in 653 dstdir=$PODMAN_TMPDIR/cp-test-out 654 mkdir -p $srcdir $dstdir 655 656 rand_filename1=$(random_string 20) 657 rand_content1=$(random_string 50) 658 rand_filename2=$(random_string 20) 659 rand_content2=$(random_string 50) 660 661 run_podman run --name cpcontainer $IMAGE sh -c \ 662 "echo $rand_content1 >/tmp/$rand_filename1; 663 echo $rand_content2 >/tmp/$rand_filename2" 664 665 # cp no longer supports wildcarding 666 run_podman 125 cp 'cpcontainer:/tmp/*' $dstdir 667 668 run_podman rm -t 0 -f cpcontainer 669 } 670 671 672 # Create a file on the host; make a symlink in the container pointing 673 # into host-only space. Try to podman-cp that symlink. It should fail. 674 @test "podman cp - will not recognize symlink pointing into host space" { 675 srcdir=$PODMAN_TMPDIR/cp-test-in 676 dstdir=$PODMAN_TMPDIR/cp-test-out 677 mkdir -p $srcdir $dstdir 678 echo "this file is on the host" >$srcdir/hostfile 679 680 run_podman run --name cpcontainer $IMAGE \ 681 sh -c "ln -s $srcdir/hostfile /tmp/badlink" 682 # This should fail because, from the container's perspective, the symlink 683 # points to a nonexistent file 684 run_podman 125 cp 'cpcontainer:/tmp/*' $dstdir/ 685 686 # FIXME: this might not be the exactly correct error message 687 is "$output" 'Error: "/tmp/\*" could not be found on container.*' 688 689 # make sure there are no files in dstdir 690 is "$(/bin/ls -1 $dstdir)" "" "incorrectly copied symlink from host" 691 692 run_podman rm -t 0 -f cpcontainer 693 } 694 695 696 # Issue #3829 - like the above, but with a level of indirection in the 697 # wildcard expansion: create a file on the host; create a symlink in 698 # the container named 'file1' pointing to this file; then another symlink 699 # in the container pointing to 'file*' (file star). Try to podman-cp 700 # this invalid double symlink. It must fail. 701 @test "podman cp - will not expand globs in host space (#3829)" { 702 srcdir=$PODMAN_TMPDIR/cp-test-in 703 dstdir=$PODMAN_TMPDIR/cp-test-out 704 mkdir -p $srcdir $dstdir 705 echo "This file is on the host" > $srcdir/hostfile 706 707 run_podman run --name cpcontainer $IMAGE \ 708 sh -c "ln -s $srcdir/hostfile file1;ln -s file\* copyme" 709 run_podman 125 cp cpcontainer:copyme $dstdir 710 711 is "$output" 'Error: "copyme*" could not be found on container.*' 712 713 # make sure there are no files in dstdir 714 is "$(/bin/ls -1 $dstdir)" "" "incorrectly copied symlink from host" 715 716 run_podman rm -t 0 -f cpcontainer 717 } 718 719 720 # Another symlink into host space, this one named '*' (star). cp should fail. 721 @test "podman cp - will not expand wildcard" { 722 srcdir=$PODMAN_TMPDIR/cp-test-in 723 dstdir=$PODMAN_TMPDIR/cp-test-out 724 mkdir -p $srcdir $dstdir 725 echo "This file lives on the host" > $srcdir/hostfile 726 727 run_podman run --name cpcontainer $IMAGE \ 728 sh -c "ln -s $srcdir/hostfile /tmp/\*" 729 run_podman 125 cp 'cpcontainer:/tmp/*' $dstdir 730 731 is "$output" 'Error: "/tmp/\*" could not be found on container.*' 732 733 # dstdir must be empty 734 is "$(/bin/ls -1 $dstdir)" "" "incorrectly copied symlink from host" 735 736 run_podman rm -t 0 -f cpcontainer 737 } 738 739 740 # THIS IS EXTREMELY WEIRD. Podman expands symlinks in weird ways. 741 @test "podman cp into container: weird symlink expansion" { 742 srcdir=$PODMAN_TMPDIR/cp-test-in 743 dstdir=$PODMAN_TMPDIR/cp-test-out 744 mkdir -p $srcdir $dstdir 745 746 rand_filename1=$(random_string 20) 747 rand_content1=$(random_string 50) 748 echo $rand_content1 > $srcdir/$rand_filename1 749 750 rand_filename2=$(random_string 20) 751 rand_content2=$(random_string 50) 752 echo $rand_content2 > $srcdir/$rand_filename2 753 754 rand_filename3=$(random_string 20) 755 rand_content3=$(random_string 50) 756 echo $rand_content3 > $srcdir/$rand_filename3 757 758 # Create tmp subdirectories in container, most with an invalid 'x' symlink 759 # Keep container running so we can exec into it. 760 run_podman run -d --name cpcontainer $IMAGE \ 761 sh -c "mkdir /tmp/d1;ln -s /tmp/nonesuch1 /tmp/d1/x; 762 mkdir /tmp/d2;ln -s /tmp/nonesuch2 /tmp/d2/x; 763 mkdir /tmp/d3; 764 trap 'exit 0' 15;echo READY;while :;do sleep 0.5;done" 765 wait_for_ready cpcontainer 766 767 # Copy file from host into container, into a file named 'x' 768 # Note that the second has a trailing slash, implying a directory. 769 # Since that destination directory doesn't exist, the cp will fail 770 run_podman cp $srcdir/$rand_filename1 cpcontainer:/tmp/d1/x 771 is "$output" "" "output from podman cp 1" 772 773 run_podman 125 cp $srcdir/$rand_filename2 cpcontainer:/tmp/d2/x/ 774 is "$output" 'Error: "/tmp/d2/x/" could not be found on container cpcontainer: no such file or directory' "cp will not create nonexistent destination directory" 775 776 run_podman cp $srcdir/$rand_filename3 cpcontainer:/tmp/d3/x 777 is "$output" "" "output from podman cp 3" 778 779 # Read back. 780 # In the first case, podman actually creates the file nonesuch1 (i.e. 781 # podman expands 'x -> nonesuch1' and, instead of overwriting x, 782 # creates an actual file). 783 run_podman exec cpcontainer cat /tmp/nonesuch1 784 is "$output" "$rand_content1" "cp creates destination file" 785 786 787 # cp into nonexistent directory should not mkdir nonesuch2 directory 788 run_podman 1 exec cpcontainer test -e /tmp/nonesuch2 789 790 # In the third case, podman (correctly imo) creates a file named 'x' 791 run_podman exec cpcontainer cat /tmp/d3/x 792 is "$output" "$rand_content3" "cp creates file named x" 793 794 run_podman rm -t 0 -f cpcontainer 795 } 796 797 798 # rhbz1741718 : file copied into container:/var/lib/foo appears as /foo 799 # (docker only, never seems to have affected podman. Make sure it never does). 800 @test "podman cp into a subdirectory matching GraphRoot" { 801 # Create tempfile with random name and content 802 srcdir=$PODMAN_TMPDIR/cp-test-in 803 mkdir -p $srcdir 804 rand_filename=$(random_string 20) 805 rand_content=$(random_string 50) 806 echo $rand_content > $srcdir/$rand_filename 807 chmod 644 $srcdir/$rand_filename 808 809 # Determine path to podman storage (eg /var/lib/c/s, or $HOME/.local/...) 810 run_podman info --format '{{.Store.GraphRoot}}' 811 graphroot=$output 812 813 # Create that directory in the container, and keep container running 814 run_podman run -d --name cpcontainer $IMAGE sh -c \ 815 "mkdir -p $graphroot; echo READY; top" 816 wait_for_ready cpcontainer 817 818 # Copy from host into container. 819 run_podman cp $srcdir/$rand_filename cpcontainer:$graphroot/$rand_filename 820 821 # ls, and confirm it's there. 822 run_podman exec cpcontainer ls -l $graphroot/$rand_filename 823 is "$output" "-rw-r--r-- .* 1 .* root .* 51 .* $graphroot/$rand_filename" \ 824 "File is copied into container in the correct (full) path" 825 826 # Confirm it has the expected content (this is unlikely to ever fail) 827 run_podman exec cpcontainer cat $graphroot/$rand_filename 828 is "$output" "$rand_content" "Contents of file copied into container" 829 830 run_podman rm -t 0 -f cpcontainer 831 } 832 833 834 @test "podman cp from stdin to container" { 835 # Create tempfile with random name and content 836 srcdir=$PODMAN_TMPDIR/cp-test-stdin 837 mkdir -p $srcdir 838 rand_filename=$(random_string 20) 839 rand_content=$(random_string 50) 840 echo $rand_content > $srcdir/$rand_filename 841 chmod 644 $srcdir/$rand_filename 842 843 # Now tar it up! 844 tar_file=$PODMAN_TMPDIR/archive.tar.gz 845 tar -zvcf $tar_file $srcdir 846 847 run_podman run -d --name cpcontainer $IMAGE sleep infinity 848 849 # NOTE: podman is supposed to auto-detect the gzip compression and 850 # decompress automatically. 851 # 852 # "-" will evaluate to "/dev/stdin" when used a source. 853 run_podman cp - cpcontainer:/tmp < $tar_file 854 run_podman exec cpcontainer cat /tmp/$srcdir/$rand_filename 855 is "$output" "$rand_content" 856 run_podman exec cpcontainer rm -rf /tmp/$srcdir 857 858 # Now for "/dev/stdin". 859 # Note: while this works, the content ends up in Nirvana. 860 # Same for Docker. 861 run_podman cp /dev/stdin cpcontainer:/tmp < $tar_file 862 863 # Error checks below ... 864 865 # Input stream must be a (compressed) tar archive. 866 run_podman 125 cp - cpcontainer:/tmp < $srcdir/$rand_filename 867 is "$output" "Error: source must be a (compressed) tar archive when copying from stdin" 868 869 # Destination must be a directory (on an existing file). 870 run_podman exec cpcontainer touch /tmp/file.txt 871 run_podman 125 cp - cpcontainer:/tmp/file.txt < $tar_file 872 is "$output" 'Error: destination must be a directory when copying from stdin' "cp from stdin to existing file" 873 874 # Destination must be a directory (on an absent path). 875 run_podman 125 cp - cpcontainer:/tmp/IdoNotExist < $tar_file 876 is "$output" 'Error: destination must be a directory when copying from stdin' "cp from stdin to absent path" 877 878 run_podman rm -t 0 -f cpcontainer 879 } 880 881 882 @test "podman cp from container to stdout" { 883 srcdir=$PODMAN_TMPDIR/cp-test-stdout 884 mkdir -p $srcdir 885 rand_content=$(random_string 50) 886 887 run_podman run -d --name cpcontainer $IMAGE sleep infinity 888 889 run_podman exec cpcontainer sh -c "echo '$rand_content' > /tmp/file.txt" 890 run_podman exec cpcontainer touch /tmp/empty.txt 891 892 # Make sure that only "-" gets special treatment. "/dev/stdout" 893 run_podman 125 cp cpcontainer:/tmp/file.txt /dev/stdout 894 is "$output" 'Error: invalid destination: "/dev/stdout" must be a directory or a regular file' 895 896 # Copying from stdout will always compress. So let's copy the previously 897 # created file from the container via stdout, untar the archive and make 898 # sure the file exists with the expected content. 899 # 900 # NOTE that we can't use run_podman because that uses the BATS 'run' 901 # function which redirects stdout and stderr. Here we need to guarantee 902 # that podman's stdout is redirected cleanly with no artifacts. 903 904 # Copy file. 905 $PODMAN cp cpcontainer:/tmp/file.txt - > $srcdir/stdout.tar 906 907 tar xvf $srcdir/stdout.tar -C $srcdir 908 is "$(< $srcdir/file.txt)" "$rand_content" "File contents: file.txt" 909 if [[ -e "$srcdir/empty.txt" ]]; then 910 die "File should not exist, but does: empty.txt" 911 fi 912 rm -f $srcdir/* 913 914 # Copy directory. 915 $PODMAN cp cpcontainer:/tmp - > $srcdir/stdout.tar 916 917 tar xvf $srcdir/stdout.tar -C $srcdir 918 is "$(< $srcdir/tmp/file.txt)" "$rand_content" "file.txt contents" 919 is "$(< $srcdir/tmp/empty.txt)" "" "empty.txt contents" 920 921 run_podman rm -t 0 -f cpcontainer 922 } 923 924 @test "podman cp --overwrite file - ctr/ctr" { 925 rand_content_file=$(random_string 50) 926 rand_content_dir=$(random_string 50) 927 928 run_podman run -d --name ctr-file $IMAGE sh -c "echo '$rand_content_file' > /tmp/foo; echo READY; sleep infinity" 929 run_podman run -d --name ctr-dir $IMAGE sh -c "mkdir /tmp/foo; echo '$rand_content_dir' > /tmp/foo/file.txt; echo READY; sleep infinity" 930 wait_for_ready ctr-file 931 wait_for_ready ctr-dir 932 933 # overwrite a directory with a file 934 run_podman 125 cp ctr-file:/tmp/foo ctr-dir:/tmp 935 if ! is_remote; then # remote just returns a 500 936 is "$output" ".* error creating \"/tmp/foo\": .*: file exists.*" 937 fi 938 run_podman cp --overwrite ctr-file:/tmp/foo ctr-dir:/tmp 939 run_podman exec ctr-dir cat /tmp/foo 940 is "$output" "$rand_content_file" "ctr-dir:/tmp/foo, after cp --overwrite, is a file" 941 942 # reset the ctr-dir container 943 run_podman exec ctr-dir sh -c "rm -rf /tmp/foo; mkdir /tmp/foo; echo '$rand_content_dir' > /tmp/foo/file.txt" 944 945 # overwrite a file with a directory 946 run_podman 125 cp ctr-dir:/tmp/foo ctr-file:/tmp 947 if ! is_remote; then # remote just returns a 500 948 is "$output" ".* error creating \"/tmp/foo\": .*: file exists.*" 949 fi 950 run_podman cp --overwrite ctr-dir:/tmp/foo ctr-file:/tmp 951 run_podman exec ctr-file cat /tmp/foo/file.txt 952 is "$output" "$rand_content_dir" 953 954 run_podman rm -t 0 -f ctr-file ctr-dir 955 } 956 957 @test "podman cp --overwrite file - ctr/host" { 958 hostdir=$PODMAN_TMPDIR/cp-test 959 mkdir -p $hostdir 960 961 rand_content_file=$(random_string 50) 962 rand_content_dir=$(random_string 50) 963 964 run_podman run -d --name ctr-file $IMAGE sh -c "echo '$rand_content_file' > /tmp/foo; echo READY; sleep infinity" 965 run_podman run -d --name ctr-dir $IMAGE sh -c "mkdir /tmp/foo; echo '$rand_content_dir' > /tmp/foo/file.txt; echo READY; sleep infinity" 966 wait_for_ready ctr-file 967 wait_for_ready ctr-dir 968 969 # overwrite a directory with a file 970 mkdir $hostdir/foo 971 run_podman 125 cp ctr-file:/tmp/foo $hostdir 972 if ! is_remote; then # remote just returns a 500 973 is "$output" ".* error creating \"/foo\": .*: file exists.*" 974 fi 975 run_podman cp --overwrite ctr-file:/tmp/foo $hostdir 976 is "$(< $hostdir/foo)" "$rand_content_file" 977 978 # overwrite a file with a directory 979 rm -rf $hostdir/foo 980 touch $hostdir/foo 981 run_podman 125 cp ctr-dir:/tmp/foo $hostdir 982 if ! is_remote; then # remote just returns a 500 983 is "$output" ".* error creating \"/foo\": .*: file exists.*" 984 fi 985 run_podman cp --overwrite ctr-dir:/tmp/foo $hostdir 986 is "$(< $hostdir/foo/file.txt)" "$rand_content_dir" 987 988 run_podman rm -t 0 -f ctr-file ctr-dir 989 } 990 991 @test "podman cp --overwrite file - host/ctr" { 992 hostdir=$PODMAN_TMPDIR/cp-test 993 mkdir -p $hostdir 994 995 rand_content_file=$(random_string 50) 996 rand_content_dir=$(random_string 50) 997 998 run_podman run -d --name ctr-dir $IMAGE sh -c "mkdir /tmp/foo; echo READY; sleep infinity" 999 run_podman run -d --name ctr-file $IMAGE sh -c "touch /tmp/foo; echo READY; sleep infinity" 1000 wait_for_ready ctr-dir 1001 wait_for_ready ctr-file 1002 1003 # overwrite a directory with a file 1004 echo "$rand_content_file" > $hostdir/foo 1005 run_podman 125 cp $hostdir/foo ctr-dir:/tmp 1006 if ! is_remote; then # remote just returns a 500 1007 is "$output" ".* error creating \"/tmp/foo\": .*: file exists.*" 1008 fi 1009 run_podman cp --overwrite $hostdir/foo ctr-dir:/tmp 1010 run_podman exec ctr-dir cat /tmp/foo 1011 is "$output" "$rand_content_file" 1012 1013 # overwrite a file with a directory 1014 rm -f $hostdir/foo 1015 mkdir $hostdir/foo 1016 echo "$rand_content_dir" > $hostdir/foo/file.txt 1017 run_podman 125 cp $hostdir/foo ctr-file:/tmp 1018 if ! is_remote; then # remote just returns a 500 1019 is "$output" ".* error creating \"/tmp/foo\": .*: file exists.*" 1020 fi 1021 run_podman cp --overwrite $hostdir/foo ctr-file:/tmp 1022 run_podman exec ctr-file cat /tmp/foo/file.txt 1023 is "$output" "$rand_content_dir" "ctr-file:/tmp/foo/file.txt, after cp --overwrite" 1024 1025 run_podman rm -t 0 -f ctr-file ctr-dir 1026 } 1027 1028 # https://github.com/containers/podman/pull/16498 1029 @test "podman cp - dot notation - host to container" { 1030 srcdir=$PODMAN_TMPDIR/src 1031 mkdir -p $srcdir 1032 mkdir -p $srcdir/test1. $srcdir/test2 1033 touch $srcdir/test1./file1 $srcdir/test2/file2 1034 1035 run_podman run -d --name=test-ctr --rm $IMAGE sleep infinity 1036 run_podman cp $srcdir/test1. test-ctr:/tmp/foo 1037 run_podman exec test-ctr /bin/ls -1 /tmp/foo/ 1038 assert "$output" = "file1" "ls ctr:/tmp/foo: only file1 exists, nothing more" 1039 1040 run_podman rm -f -t0 test-ctr 1041 } 1042 1043 @test "podman cp - dot notation - container to host" { 1044 dstdir=$PODMAN_TMPDIR/dst 1045 mkdir -p $dstdir 1046 1047 run_podman run -d --name=test-ctr --rm $IMAGE sh -c "mkdir -p /foo/test1. /foo/test2; touch /foo/test1./file1 /foo/test2/file2; echo READY;sleep infinity" 1048 wait_for_ready test-ctr 1049 1050 run_podman cp test-ctr:/foo/test1. $dstdir/foo 1051 run /bin/ls -1 $dstdir/foo 1052 assert "$output" = "file1" "ls [local]/foo: only file1 was copied, nothing more" 1053 1054 run_podman rm -f -t0 test-ctr 1055 } 1056 1057 @test "podman cp - dot notation - container to container" { 1058 run_podman run -d --name=src-ctr --rm $IMAGE sh -c "mkdir -p /foo/test1. /foo/test2; touch /foo/test1./file1 /foo/test2/file2; echo READY;sleep infinity" 1059 wait_for_ready src-ctr 1060 1061 run_podman run -d --name=dest-ctr --rm $IMAGE sleep infinity 1062 run_podman cp src-ctr:/foo/test1. dest-ctr:/foo 1063 1064 run_podman exec dest-ctr /bin/ls -1 /foo 1065 assert "$output" = "file1" "ls dest-ctr:/foo: only file1 exists, nothing more" 1066 1067 run_podman rm -f -t0 src-ctr dest-ctr 1068 } 1069 1070 function teardown() { 1071 # In case any test fails, clean up the container we left behind 1072 run_podman rm -t 0 -f --ignore cpcontainer 1073 basic_teardown 1074 } 1075 1076 # vim: filetype=sh