Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cp: treat "." and "/." correctly #9428

Merged
merged 1 commit into from
Feb 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/podman/containers/cp.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ func copyToContainer(container string, containerPath string, hostPath string) er
}

getOptions := buildahCopiah.GetOptions{
// Unless the specified path ends with ".", we want to copy the base directory.
KeepDirectoryNames: !strings.HasSuffix(hostPath, "."),
// Unless the specified points to ".", we want to copy the base directory.
KeepDirectoryNames: hostInfo.IsDir && filepath.Base(hostPath) != ".",
}
if !hostInfo.IsDir && (!containerInfo.IsDir || containerInfoErr != nil) {
// If we're having a file-to-file copy, make sure to
Expand Down
7 changes: 4 additions & 3 deletions pkg/domain/infra/abi/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package abi
import (
"context"
"io"
"path/filepath"
"strings"

buildahCopiah "github.com/containers/buildah/copier"
Expand Down Expand Up @@ -93,7 +94,7 @@ func (ic *ContainerEngine) ContainerCopyToArchive(ctx context.Context, nameOrID
containerPath = "/."
}

_, resolvedRoot, resolvedContainerPath, err := ic.containerStat(container, containerMountPoint, containerPath)
statInfo, resolvedRoot, resolvedContainerPath, err := ic.containerStat(container, containerMountPoint, containerPath)
if err != nil {
unmount()
return nil, err
Expand All @@ -110,8 +111,8 @@ func (ic *ContainerEngine) ContainerCopyToArchive(ctx context.Context, nameOrID
return func() error {
defer container.Unmount(false)
getOptions := buildahCopiah.GetOptions{
// Unless the specified path ends with ".", we want to copy the base directory.
KeepDirectoryNames: !strings.HasSuffix(resolvedContainerPath, "."),
// Unless the specified points to ".", we want to copy the base directory.
KeepDirectoryNames: statInfo.IsDir && filepath.Base(containerPath) != ".",
UIDMap: idMappings.UIDMap,
GIDMap: idMappings.GIDMap,
ChownDirs: idPair,
Expand Down
26 changes: 26 additions & 0 deletions test/system/065-cp.bats
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ load helpers
echo "${randomcontent[0]}" > $srcdir/hostfile0
echo "${randomcontent[1]}" > $srcdir/hostfile1
echo "${randomcontent[2]}" > $srcdir/hostfile2
mkdir -p $srcdir/subdir
echo "${randomcontent[2]}" > $srcdir/subdir/dotfile.

run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sleep infinity
run_podman exec cpcontainer mkdir /srv/subdir
Expand Down Expand Up @@ -50,6 +52,11 @@ load helpers
is "$output" "${randomcontent[$id]}" "$description (cp -> ctr:$dest)"
done < <(parse_table "$tests")

# Dots are special for dirs not files.
run_podman cp $srcdir/subdir/dotfile. cpcontainer:/tmp
run_podman exec cpcontainer cat /tmp/dotfile.
is "$output" "${randomcontent[2]}" "$description (cp -> ctr:$dest)"

# Host path does not exist.
run_podman 125 cp $srcdir/IdoNotExist cpcontainer:/tmp
is "$output" 'Error: ".*/IdoNotExist" could not be found on the host' \
Expand All @@ -76,12 +83,14 @@ load helpers
)
run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sleep infinity
run_podman exec cpcontainer sh -c "echo ${randomcontent[0]} > /tmp/containerfile"
run_podman exec cpcontainer sh -c "echo ${randomcontent[0]} > /tmp/dotfile."
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"

# 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/
0 | /tmp/dotfile. | | /dotfile. | copy to srcdir/
0 | /tmp/containerfile | / | /containerfile | copy to srcdir/
0 | /tmp/containerfile | /. | /containerfile | copy to srcdir/.
0 | /tmp/containerfile | /newfile | /newfile | copy to srcdir/newfile
Expand Down Expand Up @@ -117,12 +126,18 @@ load helpers
echo "${randomcontent[0]}" > $srcdir/hostfile0
echo "${randomcontent[1]}" > $srcdir/hostfile1

# "." and "dir/." will copy the contents, so make sure that a dir ending
# with dot is treated correctly.
mkdir -p $srcdir.
cp $srcdir/* $srcdir./

run_podman run -d --name cpcontainer --workdir=/srv $IMAGE sleep infinity
run_podman exec cpcontainer mkdir /srv/subdir

# format is: <source arg to cp (appended to srcdir)> | <destination arg to cp> | <full dest path> | <test name>
tests="
| / | /dir-test | copy to root
. | / | /dir-test. | copy dotdir to root
/ | /tmp | /tmp/dir-test | copy to tmp
/. | /usr/ | /usr/ | copy contents of dir to usr/
| . | /srv/dir-test | copy to workdir (rel path)
Expand Down Expand Up @@ -153,6 +168,9 @@ load helpers
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'
# "." 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
Expand All @@ -174,6 +192,14 @@ load helpers
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.

run_podman rm -f cpcontainer
}
Expand Down