Skip to content

Commit

Permalink
Merge pull request #45720 from ndeloof/copy_uidgid
Browse files Browse the repository at this point in the history
fix `docker cp -a` failing to access `/` in container
  • Loading branch information
thaJeztah committed Jun 13, 2023
2 parents 4bef3e9 + 3cc5d62 commit a978888
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 20 deletions.
54 changes: 35 additions & 19 deletions integration/container/copy_test.go
Expand Up @@ -65,6 +65,34 @@ func TestCopyToContainerPathDoesNotExist(t *testing.T) {
func TestCopyEmptyFile(t *testing.T) {
defer setupTest(t)()

ctx := context.Background()
apiclient := testEnv.APIClient()
cid := container.Create(ctx, t, apiclient)

// empty content
dstDir, _ := makeEmptyArchive(t)
err := apiclient.CopyToContainer(ctx, cid, dstDir, bytes.NewReader([]byte("")), types.CopyToContainerOptions{})
assert.NilError(t, err)

// tar with empty file
dstDir, preparedArchive := makeEmptyArchive(t)
err = apiclient.CopyToContainer(ctx, cid, dstDir, preparedArchive, types.CopyToContainerOptions{})
assert.NilError(t, err)

// tar with empty file archive mode
dstDir, preparedArchive = makeEmptyArchive(t)
err = apiclient.CopyToContainer(ctx, cid, dstDir, preparedArchive, types.CopyToContainerOptions{
CopyUIDGID: true,
})
assert.NilError(t, err)

// copy from empty file
rdr, _, err := apiclient.CopyFromContainer(ctx, cid, dstDir)
assert.NilError(t, err)
defer rdr.Close()
}

func makeEmptyArchive(t *testing.T) (string, io.ReadCloser) {
tmpDir := t.TempDir()
srcPath := filepath.Join(tmpDir, "empty-file.txt")
err := os.WriteFile(srcPath, []byte(""), 0400)
Expand All @@ -77,30 +105,18 @@ func TestCopyEmptyFile(t *testing.T) {

srcArchive, err := archive.TarResource(srcInfo)
assert.NilError(t, err)
defer srcArchive.Close()
t.Cleanup(func() {
srcArchive.Close()
})

ctrPath := "/empty-file.txt"
dstInfo := archive.CopyInfo{Path: ctrPath}
dstDir, preparedArchive, err := archive.PrepareArchiveCopy(srcArchive, srcInfo, dstInfo)
assert.NilError(t, err)
defer preparedArchive.Close()

ctx := context.Background()
apiclient := testEnv.APIClient()
cid := container.Create(ctx, t, apiclient)

// empty content
err = apiclient.CopyToContainer(ctx, cid, dstDir, bytes.NewReader([]byte("")), types.CopyToContainerOptions{})
assert.NilError(t, err)

// tar with empty file
err = apiclient.CopyToContainer(ctx, cid, dstDir, preparedArchive, types.CopyToContainerOptions{})
assert.NilError(t, err)

// copy from empty file
rdr, _, err := apiclient.CopyFromContainer(ctx, cid, dstDir)
assert.NilError(t, err)
defer rdr.Close()
t.Cleanup(func() {
preparedArchive.Close()
})
return dstDir, preparedArchive
}

func TestCopyToContainerPathIsNotDir(t *testing.T) {
Expand Down
5 changes: 4 additions & 1 deletion pkg/idtools/idtools_unix.go
Expand Up @@ -166,7 +166,10 @@ func callGetent(database, key string) (io.Reader, error) {
if getentCmd == "" {
return nil, fmt.Errorf("unable to find getent command")
}
out, err := exec.Command(getentCmd, database, key).CombinedOutput()
command := exec.Command(getentCmd, database, key)
// we run getent within container filesystem, but without /dev so /dev/null is not available for exec to mock stdin
command.Stdin = io.NopCloser(bytes.NewReader(nil))
out, err := command.CombinedOutput()
if err != nil {
exitCode, errC := getExitCode(err)
if errC != nil {
Expand Down

0 comments on commit a978888

Please sign in to comment.