Merge pull request #45748 from thaJeztah/24.0_backport_copy_uidgid

[24.0 backport] fix docker cp -a failing to access / in container (run `getent` with a noop stdin)
This commit is contained in:
Bjorn Neergaard 2023-06-14 10:09:30 -06:00 committed by GitHub
commit 3d96894184
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 20 deletions

View file

@ -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)
@ -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) {

View file

@ -167,7 +167,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 {