mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #5954 from vieux/fix_cp_error
Ignore lchown error on docker cp
This commit is contained in:
commit
a94a87778c
6 changed files with 51 additions and 10 deletions
|
@ -91,6 +91,8 @@ RUN git config --global user.email 'docker-dummy@example.com'
|
||||||
|
|
||||||
# Add an unprivileged user to be used for tests which need it
|
# Add an unprivileged user to be used for tests which need it
|
||||||
RUN adduser unprivilegeduser
|
RUN adduser unprivilegeduser
|
||||||
|
RUN groupadd docker
|
||||||
|
RUN gpasswd -a unprivilegeduser docker
|
||||||
|
|
||||||
VOLUME /var/lib/docker
|
VOLUME /var/lib/docker
|
||||||
WORKDIR /go/src/github.com/dotcloud/docker
|
WORKDIR /go/src/github.com/dotcloud/docker
|
||||||
|
|
|
@ -2058,7 +2058,7 @@ func (cli *DockerCli) CmdCp(args ...string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if statusCode == 200 {
|
if statusCode == 200 {
|
||||||
if err := archive.Untar(stream, copyData.Get("HostPath"), nil); err != nil {
|
if err := archive.Untar(stream, copyData.Get("HostPath"), &archive.TarOptions{NoLchown: true}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ type (
|
||||||
TarOptions struct {
|
TarOptions struct {
|
||||||
Includes []string
|
Includes []string
|
||||||
Compression Compression
|
Compression Compression
|
||||||
|
NoLchown bool
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -179,7 +180,7 @@ func addTarFile(path, name string, tw *tar.Writer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader) error {
|
func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, Lchown bool) error {
|
||||||
// hdr.Mode is in linux format, which we can use for sycalls,
|
// hdr.Mode is in linux format, which we can use for sycalls,
|
||||||
// but for os.Foo() calls we need the mode converted to os.FileMode,
|
// but for os.Foo() calls we need the mode converted to os.FileMode,
|
||||||
// so use hdrInfo.Mode() (they differ for e.g. setuid bits)
|
// so use hdrInfo.Mode() (they differ for e.g. setuid bits)
|
||||||
|
@ -240,7 +241,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader) e
|
||||||
return fmt.Errorf("Unhandled tar header type %d\n", hdr.Typeflag)
|
return fmt.Errorf("Unhandled tar header type %d\n", hdr.Typeflag)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.Lchown(path, hdr.Uid, hdr.Gid); err != nil {
|
if err := os.Lchown(path, hdr.Uid, hdr.Gid); err != nil && Lchown {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,8 +416,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := createTarFile(path, dest, hdr, tr, options == nil || !options.NoLchown); err != nil {
|
||||||
if err := createTarFile(path, dest, hdr, tr); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package archive
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/dotcloud/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
@ -11,6 +10,8 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/dotcloud/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCmdStreamLargeStderr(t *testing.T) {
|
func TestCmdStreamLargeStderr(t *testing.T) {
|
||||||
|
@ -132,7 +133,7 @@ func TestTarUntar(t *testing.T) {
|
||||||
// Failing prevents the archives from being uncompressed during ADD
|
// Failing prevents the archives from being uncompressed during ADD
|
||||||
func TestTypeXGlobalHeaderDoesNotFail(t *testing.T) {
|
func TestTypeXGlobalHeaderDoesNotFail(t *testing.T) {
|
||||||
hdr := tar.Header{Typeflag: tar.TypeXGlobalHeader}
|
hdr := tar.Header{Typeflag: tar.TypeXGlobalHeader}
|
||||||
err := createTarFile("pax_global_header", "some_dir", &hdr, nil)
|
err := createTarFile("pax_global_header", "some_dir", &hdr, nil, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,14 @@ package archive
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/dotcloud/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/dotcloud/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Linux device nodes are a bit weird due to backwards compat with 16 bit device nodes.
|
// Linux device nodes are a bit weird due to backwards compat with 16 bit device nodes.
|
||||||
|
@ -79,7 +80,7 @@ func ApplyLayer(dest string, layer ArchiveReader) error {
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(aufsTempdir)
|
defer os.RemoveAll(aufsTempdir)
|
||||||
}
|
}
|
||||||
if err := createTarFile(filepath.Join(aufsTempdir, basename), dest, hdr, tr); err != nil {
|
if err := createTarFile(filepath.Join(aufsTempdir, basename), dest, hdr, tr, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +127,7 @@ func ApplyLayer(dest string, layer ArchiveReader) error {
|
||||||
srcData = tmpFile
|
srcData = tmpFile
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := createTarFile(path, dest, srcHdr, srcData); err != nil {
|
if err := createTarFile(path, dest, srcHdr, srcData, true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -206,3 +207,39 @@ func TestCpAbsolutePath(t *testing.T) {
|
||||||
|
|
||||||
logDone("cp - absolute paths relative to container's rootfs")
|
logDone("cp - absolute paths relative to container's rootfs")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that cp with unprivileged user doesn't return any error
|
||||||
|
func TestCpUnprivilegedUser(t *testing.T) {
|
||||||
|
out, exitCode, err := cmd(t, "run", "-d", "busybox", "/bin/sh", "-c", "touch "+cpTestName)
|
||||||
|
if err != nil || exitCode != 0 {
|
||||||
|
t.Fatal("failed to create a container", out, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanedContainerID := stripTrailingCharacters(out)
|
||||||
|
defer deleteContainer(cleanedContainerID)
|
||||||
|
|
||||||
|
out, _, err = cmd(t, "wait", cleanedContainerID)
|
||||||
|
if err != nil || stripTrailingCharacters(out) != "0" {
|
||||||
|
t.Fatal("failed to set up container", out, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpdir, err := ioutil.TempDir("", "docker-integration")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
|
if err = os.Chmod(tmpdir, 0777); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
path := cpTestName
|
||||||
|
|
||||||
|
_, _, err = runCommandWithOutput(exec.Command("su", "unprivilegeduser", "-c", dockerBinary+" cp "+cleanedContainerID+":"+path+" "+tmpdir))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't copy with unprivileged user: %s:%s %s", cleanedContainerID, path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logDone("cp - unprivileged user")
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue