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