Merge pull request #28923 from erikh/fix-copy

Fix copy API (`docker cp`, etc) uid/gid handling
Upstream-commit: d40a17ffc2f6592396a3dfc0f5ebe396c2107536
Component: engine
This commit is contained in:
Anusha Ragunathan
2017-04-12 08:21:17 -07:00
committed by GitHub
14 changed files with 209 additions and 99 deletions
+14 -9
View File
@@ -83,7 +83,7 @@ func (daemon *Daemon) ContainerArchivePath(name string, path string) (content io
// be ErrExtractPointNotDirectory. If noOverwriteDirNonDir is true then it will
// be an error if unpacking the given content would cause an existing directory
// to be replaced with a non-directory and vice versa.
func (daemon *Daemon) ContainerExtractToDir(name, path string, noOverwriteDirNonDir bool, content io.Reader) error {
func (daemon *Daemon) ContainerExtractToDir(name, path string, copyUIDGID, noOverwriteDirNonDir bool, content io.Reader) error {
container, err := daemon.GetContainer(name)
if err != nil {
return err
@@ -94,7 +94,7 @@ func (daemon *Daemon) ContainerExtractToDir(name, path string, noOverwriteDirNon
return err
}
return daemon.containerExtractToDir(container, path, noOverwriteDirNonDir, content)
return daemon.containerExtractToDir(container, path, copyUIDGID, noOverwriteDirNonDir, content)
}
// containerStatPath stats the filesystem resource at the specified path in this
@@ -196,7 +196,7 @@ func (daemon *Daemon) containerArchivePath(container *container.Container, path
// noOverwriteDirNonDir is true then it will be an error if unpacking the
// given content would cause an existing directory to be replaced with a non-
// directory and vice versa.
func (daemon *Daemon) containerExtractToDir(container *container.Container, path string, noOverwriteDirNonDir bool, content io.Reader) (err error) {
func (daemon *Daemon) containerExtractToDir(container *container.Container, path string, copyUIDGID, noOverwriteDirNonDir bool, content io.Reader) (err error) {
container.Lock()
defer container.Unlock()
@@ -279,13 +279,18 @@ func (daemon *Daemon) containerExtractToDir(container *container.Container, path
return ErrRootFSReadOnly
}
uid, gid := daemon.GetRemappedUIDGID()
options := &archive.TarOptions{
NoOverwriteDirNonDir: noOverwriteDirNonDir,
ChownOpts: &archive.TarChownOptions{
UID: uid, GID: gid, // TODO: should all ownership be set to root (either real or remapped)?
},
options := daemon.defaultTarCopyOptions(noOverwriteDirNonDir)
if copyUIDGID {
var err error
// tarCopyOptions will appropriately pull in the right uid/gid for the
// user/group and will set the options.
options, err = daemon.tarCopyOptions(container, noOverwriteDirNonDir)
if err != nil {
return err
}
}
if err := chrootarchive.Untar(content, resolvedPath, options); err != nil {
return err
}
@@ -0,0 +1,16 @@
package daemon
import (
"github.com/docker/docker/pkg/archive"
)
// defaultTarCopyOptions is the setting that is used when unpacking an archive
// for a copy API event.
func (daemon *Daemon) defaultTarCopyOptions(noOverwriteDirNonDir bool) *archive.TarOptions {
uidMaps, gidMaps := daemon.GetUIDGIDMaps()
return &archive.TarOptions{
NoOverwriteDirNonDir: noOverwriteDirNonDir,
UIDMaps: uidMaps,
GIDMaps: gidMaps,
}
}
@@ -0,0 +1,28 @@
// +build !windows
package daemon
import (
"github.com/docker/docker/container"
"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/idtools"
)
func (daemon *Daemon) tarCopyOptions(container *container.Container, noOverwriteDirNonDir bool) (*archive.TarOptions, error) {
if container.Config.User == "" {
return daemon.defaultTarCopyOptions(noOverwriteDirNonDir), nil
}
user, err := idtools.LookupUser(container.Config.User)
if err != nil {
return nil, err
}
return &archive.TarOptions{
NoOverwriteDirNonDir: noOverwriteDirNonDir,
ChownOpts: &archive.TarChownOptions{
UID: user.Uid,
GID: user.Gid,
},
}, nil
}
@@ -0,0 +1,12 @@
// +build windows
package daemon
import (
"github.com/docker/docker/container"
"github.com/docker/docker/pkg/archive"
)
func (daemon *Daemon) tarCopyOptions(container *container.Container, noOverwriteDirNonDir bool) (*archive.TarOptions, error) {
return daemon.defaultTarCopyOptions(noOverwriteDirNonDir), nil
}