summaryrefslogtreecommitdiff
path: root/test/system/065-cp.bats
diff options
context:
space:
mode:
authorValentin Rothberg <rothberg@redhat.com>2021-03-02 09:20:53 +0100
committerValentin Rothberg <rothberg@redhat.com>2021-03-04 15:43:12 +0100
commita090301bbb10424ce4f99e40c97959f0e8664718 (patch)
tree3b2596e3d152204d35162b1ca89f524c5803ad8c /test/system/065-cp.bats
parent833670079c5b1f95fbb7c9bb8ba9095f1c66c7b4 (diff)
downloadpodman-a090301bbb10424ce4f99e40c97959f0e8664718.tar.gz
podman-a090301bbb10424ce4f99e40c97959f0e8664718.tar.bz2
podman-a090301bbb10424ce4f99e40c97959f0e8664718.zip
podman cp: support copying on tmpfs mounts
Traditionally, the path resolution for containers has been resolved on the *host*; relative to the container's mount point or relative to specified bind mounts or volumes. While this works nicely for non-running containers, it poses a problem for running ones. In that case, certain kinds of mounts (e.g., tmpfs) will not resolve correctly. A tmpfs is held in memory and hence cannot be resolved relatively to the container's mount point. A copy operation will succeed but the data will not show up inside the container. To support these kinds of mounts, we need to join the *running* container's mount namespace (and PID namespace) when copying. Note that this change implies moving the copy and stat logic into `libpod` since we need to keep the container locked to avoid race conditions. The immediate benefit is that all logic is now inside `libpod`; the code isn't scattered anymore. Further note that Docker does not support copying to tmpfs mounts. Tests have been extended to cover *both* path resolutions for running and created containers. New tests have been added to exercise the tmpfs-mount case. For the record: Some tests could be improved by using `start -a` instead of a start-exec sequence. Unfortunately, `start -a` is flaky in the CI which forced me to use the more expensive start-exec option. Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'test/system/065-cp.bats')
-rw-r--r--test/system/065-cp.bats220
1 files changed, 163 insertions, 57 deletions
diff --git a/test/system/065-cp.bats b/test/system/065-cp.bats
index 312106b36..88ed983d8 100644
--- a/test/system/065-cp.bats
+++ b/test/system/065-cp.bats
@@ -15,6 +15,7 @@ load helpers
random-1-$(random_string 15)
random-2-$(random_string 20)
)
+
echo "${randomcontent[0]}" > $srcdir/hostfile0
echo "${randomcontent[1]}" > $srcdir/hostfile1
echo "${randomcontent[2]}" > $srcdir/hostfile2
@@ -24,6 +25,10 @@ load helpers
run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sleep infinity
run_podman exec cpcontainer mkdir /srv/subdir
+ # Commit the image for testing non-running containers
+ run_podman commit -q cpcontainer
+ cpimage="$output"
+
# format is: <id> | <destination arg to cp> | <full dest path> | <test name>
# where:
# id is 0-2, one of the random strings/files
@@ -44,8 +49,7 @@ load helpers
0 | subdir | /srv/subdir/hostfile0 | copy to workdir/subdir
"
- # Copy one of the files into container, exec+cat, confirm the file
- # is there and matches what we expect
+ # RUNNING container
while read id dest dest_fullname description; do
run_podman cp $srcdir/hostfile$id cpcontainer:$dest
run_podman exec cpcontainer cat $dest_fullname
@@ -67,6 +71,44 @@ load helpers
is "$output" 'Error: "/IdoNotExist/" could not be found on container cpcontainer: No such file or directory' \
"copy into nonexistent path in container"
+ run_podman kill cpcontainer
+ run_podman rm -f cpcontainer
+
+ # CREATED container
+ while read id dest dest_fullname description; do
+ run_podman create --name cpcontainer --workdir=/srv $cpimage sleep infinity
+ run_podman cp $srcdir/hostfile$id cpcontainer:$dest
+ run_podman start cpcontainer
+ run_podman exec cpcontainer cat $dest_fullname
+ is "$output" "${randomcontent[$id]}" "$description (cp -> ctr:$dest)"
+ run_podman kill cpcontainer
+ run_podman rm -f cpcontainer
+ done < <(parse_table "$tests")
+
+ run_podman rmi -f $cpimage
+}
+
+@test "podman cp file from host to container tmpfs mount" {
+ srcdir=$PODMAN_TMPDIR/cp-test-file-host-to-ctr
+ mkdir -p $srcdir
+ content=tmpfile-content$(random_string 20)
+ echo $content > $srcdir/file
+
+ # RUNNING container
+ run_podman run -d --mount type=tmpfs,dst=/tmp --name cpcontainer $IMAGE sleep infinity
+ run_podman cp $srcdir/file cpcontainer:/tmp
+ run_podman exec cpcontainer cat /tmp/file
+ is "$output" "${content}" "cp to running container's tmpfs"
+ run_podman kill cpcontainer
+ run_podman rm -f cpcontainer
+
+ # CREATED container (with copy up)
+ run_podman create --mount type=tmpfs,dst=/tmp --name cpcontainer $IMAGE sleep infinity
+ run_podman cp $srcdir/file cpcontainer:/tmp
+ run_podman start cpcontainer
+ run_podman exec cpcontainer cat /tmp/file
+ is "$output" "${content}" "cp to created container's tmpfs"
+ run_podman kill cpcontainer
run_podman rm -f cpcontainer
}
@@ -87,6 +129,10 @@ load helpers
run_podman exec cpcontainer sh -c "echo ${randomcontent[1]} > /srv/containerfile1"
run_podman exec cpcontainer sh -c "mkdir /srv/subdir; echo ${randomcontent[2]} > /srv/subdir/containerfile2"
+ # Commit the image for testing non-running containers
+ run_podman commit -q cpcontainer
+ cpimage="$output"
+
# format is: <id> | <source arg to cp> | <destination arg (appended to $srcdir) to cp> | <full dest path (appended to $srcdir)> | <test name>
tests="
0 | /tmp/containerfile | | /containerfile | copy to srcdir/
@@ -98,20 +144,33 @@ load helpers
2 | subdir/containerfile2 | / | /containerfile2 | copy from workdir/subdir (rel path) to srcdir
"
- # Copy one of the files to the host, cat, confirm the file
- # is there and matches what we expect
+ # RUNNING container
while read id src dest dest_fullname description; do
# dest may be "''" for empty table cells
if [[ $dest == "''" ]];then
unset dest
fi
run_podman cp cpcontainer:$src "$srcdir$dest"
- run cat $srcdir$dest_fullname
- is "$output" "${randomcontent[$id]}" "$description (cp ctr:$src to \$srcdir$dest)"
- rm $srcdir/$dest_fullname
+ is "$(< $srcdir$dest_fullname)" "${randomcontent[$id]}" "$description (cp ctr:$src to \$srcdir$dest)"
+ rm $srcdir$dest_fullname
done < <(parse_table "$tests")
+ run_podman kill cpcontainer
+ run_podman rm -f cpcontainer
+ # Created container
+ run_podman create --name cpcontainer --workdir=/srv $cpimage
+ while read id src dest dest_fullname description; do
+ # dest may be "''" for empty table cells
+ if [[ $dest == "''" ]];then
+ unset dest
+ fi
+ run_podman cp cpcontainer:$src "$srcdir$dest"
+ is "$(< $srcdir$dest_fullname)" "${randomcontent[$id]}" "$description (cp ctr:$src to \$srcdir$dest)"
+ rm $srcdir$dest_fullname
+ done < <(parse_table "$tests")
run_podman rm -f cpcontainer
+
+ run_podman rmi -f $cpimage
}
@@ -134,6 +193,10 @@ load helpers
run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sleep infinity
run_podman exec cpcontainer mkdir /srv/subdir
+ # Commit the image for testing non-running containers
+ run_podman commit -q cpcontainer
+ cpimage="$output"
+
# format is: <source arg to cp (appended to srcdir)> | <destination arg to cp> | <full dest path> | <test name>
tests="
| / | /dir-test | copy to root
@@ -141,9 +204,10 @@ load helpers
/ | /tmp | /tmp/dir-test | copy to tmp
/. | /usr/ | /usr/ | copy contents of dir to usr/
| . | /srv/dir-test | copy to workdir (rel path)
- | subdir/. | /srv/subdir/dir-test | copy to workdir subdir (rel path)
+ | subdir/. | /srv/subdir/dir-test | copy to workdir subdir (rel path)
"
+ # RUNNING container
while read src dest dest_fullname description; do
# src may be "''" for empty table cells
if [[ $src == "''" ]];then
@@ -156,52 +220,97 @@ load helpers
run_podman exec cpcontainer cat $dest_fullname/hostfile1
is "$output" "${randomcontent[1]}" "$description (cp -> ctr:$dest)"
done < <(parse_table "$tests")
-
+ run_podman kill cpcontainer
run_podman rm -f cpcontainer
+
+ # CREATED container
+ while read src dest dest_fullname description; do
+ # src may be "''" for empty table cells
+ if [[ $src == "''" ]];then
+ unset src
+ fi
+ run_podman create --name cpcontainer --workdir=/srv $cpimage sleep infinity
+ run_podman cp $srcdir$src cpcontainer:$dest
+ run_podman start cpcontainer
+ run_podman exec cpcontainer cat $dest_fullname/hostfile0 $dest_fullname/hostfile1
+ is "${lines[0]}" "${randomcontent[0]}" "$description (cp -> ctr:$dest)"
+ is "${lines[1]}" "${randomcontent[1]}" "$description (cp -> ctr:$dest)"
+ run_podman kill cpcontainer
+ run_podman rm -f cpcontainer
+ done < <(parse_table "$tests")
+
+ run_podman rmi -f $cpimage
}
@test "podman cp dir from container to host" {
- srcdir=$PODMAN_TMPDIR/dir-test
- mkdir -p $srcdir
+ destdir=$PODMAN_TMPDIR/cp-test-dir-ctr-to-host
+ mkdir -p $destdir
+ # Create 2 files with random content in the container.
+ local -a randomcontent=(
+ random-0-$(random_string 10)
+ random-1-$(random_string 15)
+ )
run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sleep infinity
- run_podman exec cpcontainer sh -c 'mkdir /srv/subdir; echo "This first file is on the container" > /srv/subdir/containerfile1'
- run_podman exec cpcontainer sh -c 'echo "This second file is on the container as well" > /srv/subdir/containerfile2'
+ run_podman exec cpcontainer sh -c "mkdir /srv/subdir; echo ${randomcontent[0]} > /srv/subdir/containerfile0"
+ run_podman exec cpcontainer sh -c "echo ${randomcontent[1]} > /srv/subdir/containerfile1"
# "." and "dir/." will copy the contents, so make sure that a dir ending
# with dot is treated correctly.
run_podman exec cpcontainer sh -c 'mkdir /tmp/subdir.; cp /srv/subdir/* /tmp/subdir./'
- run_podman cp cpcontainer:/srv $srcdir
- run cat $srcdir/srv/subdir/containerfile1
- is "$output" "This first file is on the container"
- run cat $srcdir/srv/subdir/containerfile2
- is "$output" "This second file is on the container as well"
- rm -rf $srcdir/srv/subdir
-
- run_podman cp cpcontainer:/srv/. $srcdir
- run ls $srcdir/subdir
- run cat $srcdir/subdir/containerfile1
- is "$output" "This first file is on the container"
- run cat $srcdir/subdir/containerfile2
- is "$output" "This second file is on the container as well"
- rm -rf $srcdir/subdir
-
- run_podman cp cpcontainer:/srv/subdir/. $srcdir
- run cat $srcdir/containerfile1
- is "$output" "This first file is on the container"
- run cat $srcdir/containerfile2
- is "$output" "This second file is on the container as well"
- rm -rf $srcdir/subdir
-
- run_podman cp cpcontainer:/tmp/subdir. $srcdir
- run cat $srcdir/subdir./containerfile1
- is "$output" "This first file is on the container"
- run cat $srcdir/subdir./containerfile2
- is "$output" "This second file is on the container as well"
- rm -rf $srcdir/subdir.
+ # Commit the image for testing non-running containers
+ run_podman commit -q cpcontainer
+ cpimage="$output"
+
+ # format is: <source arg to cp (appended to /srv)> | <full dest path> | <test name>
+ tests="
+ /srv | /srv/subdir | copy /srv
+ /srv/ | /srv/subdir | copy /srv/
+ /srv/. | /subdir | copy /srv/.
+ /srv/subdir/. | | copy /srv/subdir/.
+ /tmp/subdir. | /subdir. | copy /tmp/subdir.
+"
+
+ # RUNNING container
+ while read src dest_fullname description; do
+ if [[ $src == "''" ]];then
+ unset src
+ fi
+ if [[ $dest == "''" ]];then
+ unset dest
+ fi
+ if [[ $dest_fullname == "''" ]];then
+ unset dest_fullname
+ fi
+ run_podman cp cpcontainer:$src $destdir
+ is "$(< $destdir$dest_fullname/containerfile0)" "${randomcontent[0]}" "$description"
+ is "$(< $destdir$dest_fullname/containerfile1)" "${randomcontent[1]}" "$description"
+ rm -rf $destdir/*
+ done < <(parse_table "$tests")
+ run_podman kill cpcontainer
+ run_podman rm -f cpcontainer
+ # CREATED container
+ run_podman create --name cpcontainer --workdir=/srv $cpimage
+ while read src dest_fullname description; do
+ if [[ $src == "''" ]];then
+ unset src
+ fi
+ if [[ $dest == "''" ]];then
+ unset dest
+ fi
+ if [[ $dest_fullname == "''" ]];then
+ unset dest_fullname
+ fi
+ run_podman cp cpcontainer:$src $destdir
+ is "$(< $destdir$dest_fullname/containerfile0)" "${randomcontent[0]}" "$description"
+ is "$(< $destdir$dest_fullname/containerfile1)" "${randomcontent[1]}" "$description"
+ rm -rf $destdir/*
+ done < <(parse_table "$tests")
run_podman rm -f cpcontainer
+
+ run_podman rmi -f $cpimage
}
@@ -228,9 +337,7 @@ load helpers
run_podman create --name cpcontainer -v $volume1:/tmp/volume -v $volume2:/tmp/volume/sub-volume $IMAGE
run_podman cp $srcdir/hostfile cpcontainer:/tmp/volume/sub-volume
-
- run cat $volume2_mount/hostfile
- is "$output" "This file should be in volume2"
+ is "$(< $volume2_mount/hostfile)" "This file should be in volume2"
# Volume 1 must be empty.
run ls $volume1_mount
@@ -254,9 +361,7 @@ load helpers
run_podman create --name cpcontainer -v $volume:/tmp/volume -v $mountdir:/tmp/volume/mount $IMAGE
run_podman cp $srcdir/hostfile cpcontainer:/tmp/volume/mount
-
- run cat $mountdir/hostfile
- is "$output" "This file should be in the mount"
+ is "$(< $mountdir/hostfile)" "This file should be in the mount"
run_podman rm -f cpcontainer
run_podman volume rm $volume
@@ -284,7 +389,7 @@ load helpers
# cp no longer supports wildcarding
run_podman 125 cp 'cpcontainer:/tmp/*' $dstdir
- run_podman rm cpcontainer
+ run_podman rm -f cpcontainer
}
@@ -308,7 +413,7 @@ load helpers
# make sure there are no files in dstdir
is "$(/bin/ls -1 $dstdir)" "" "incorrectly copied symlink from host"
- run_podman rm cpcontainer
+ run_podman rm -f cpcontainer
}
@@ -332,7 +437,7 @@ load helpers
# make sure there are no files in dstdir
is "$(/bin/ls -1 $dstdir)" "" "incorrectly copied symlink from host"
- run_podman rm cpcontainer
+ run_podman rm -f cpcontainer
}
@@ -352,7 +457,7 @@ load helpers
# dstdir must be empty
is "$(/bin/ls -1 $dstdir)" "" "incorrectly copied symlink from host"
- run_podman rm cpcontainer
+ run_podman rm -f cpcontainer
}
@@ -409,6 +514,7 @@ load helpers
run_podman exec cpcontainer cat /tmp/d3/x
is "$output" "$rand_content3" "cp creates file named x"
+ run_podman kill cpcontainer
run_podman rm -f cpcontainer
}
@@ -446,6 +552,7 @@ load helpers
run_podman exec cpcontainer cat $graphroot/$rand_filename
is "$output" "$rand_content" "Contents of file copied into container"
+ run_podman kill cpcontainer
run_podman rm -f cpcontainer
}
@@ -494,6 +601,7 @@ load helpers
run_podman 125 cp - cpcontainer:/tmp/IdoNotExist < $tar_file
is "$output" 'Error: destination must be a directory when copying from stdin'
+ run_podman kill cpcontainer
run_podman rm -f cpcontainer
}
@@ -527,8 +635,7 @@ load helpers
fi
tar xvf $srcdir/stdout.tar -C $srcdir
- run cat $srcdir/file.txt
- is "$output" "$rand_content"
+ is "$(< $srcdir/file.txt)" "$rand_content"
run 1 ls $srcdir/empty.txt
rm -f $srcdir/*
@@ -539,11 +646,10 @@ load helpers
fi
tar xvf $srcdir/stdout.tar -C $srcdir
- run cat $srcdir/tmp/file.txt
- is "$output" "$rand_content"
- run cat $srcdir/tmp/empty.txt
- is "$output" ""
+ is "$(< $srcdir/tmp/file.txt)" "$rand_content"
+ is "$(< $srcdir/tmp/empty.txt)" ""
+ run_podman kill cpcontainer
run_podman rm -f cpcontainer
}