Add ADD/COPY --chown flag support to Windows

This implements chown support on Windows. Built-in accounts as well
as accounts included in the SAM database of the container are supported.

NOTE: IDPair is now named Identity and IDMappings is now named
IdentityMapping.

The following are valid examples:
ADD --chown=Guest . <some directory>
COPY --chown=Administrator . <some directory>
COPY --chown=Guests . <some directory>
COPY --chown=ContainerUser . <some directory>

On Windows an owner is only granted the permission to read the security
descriptor and read/write the discretionary access control list. This
fix also grants read/write and execute permissions to the owner.

Signed-off-by: Salahuddin Khan <salah@docker.com>
Upstream-commit: 763d8392612942ff5c32a35f8bdafd7ae93d3321
Component: engine
This commit is contained in:
Salahuddin Khan
2018-08-13 21:59:11 -07:00
parent 96af87df0a
commit 7414934b6c
64 changed files with 610 additions and 301 deletions
+12 -12
View File
@@ -46,18 +46,18 @@ type activeMount struct {
// New instantiates a new Root instance with the provided scope. Scope
// is the base path that the Root instance uses to store its
// volumes. The base path is created here if it does not exist.
func New(scope string, rootIDs idtools.IDPair) (*Root, error) {
func New(scope string, rootIdentity idtools.Identity) (*Root, error) {
rootDirectory := filepath.Join(scope, volumesPathName)
if err := idtools.MkdirAllAndChown(rootDirectory, 0700, rootIDs); err != nil {
if err := idtools.MkdirAllAndChown(rootDirectory, 0700, rootIdentity); err != nil {
return nil, err
}
r := &Root{
scope: scope,
path: rootDirectory,
volumes: make(map[string]*localVolume),
rootIDs: rootIDs,
scope: scope,
path: rootDirectory,
volumes: make(map[string]*localVolume),
rootIdentity: rootIdentity,
}
dirs, err := ioutil.ReadDir(rootDirectory)
@@ -101,11 +101,11 @@ func New(scope string, rootIDs idtools.IDPair) (*Root, error) {
// manages the creation/removal of volumes. It uses only standard vfs
// commands to create/remove dirs within its provided scope.
type Root struct {
m sync.Mutex
scope string
path string
volumes map[string]*localVolume
rootIDs idtools.IDPair
m sync.Mutex
scope string
path string
volumes map[string]*localVolume
rootIdentity idtools.Identity
}
// List lists all the volumes
@@ -146,7 +146,7 @@ func (r *Root) Create(name string, opts map[string]string) (volume.Volume, error
}
path := r.DataPath(name)
if err := idtools.MkdirAllAndChown(path, 0755, r.rootIDs); err != nil {
if err := idtools.MkdirAllAndChown(path, 0755, r.rootIdentity); err != nil {
return nil, errors.Wrapf(errdefs.System(err), "error while creating volume path '%s'", path)
}
+9 -9
View File
@@ -38,7 +38,7 @@ func TestRemove(t *testing.T) {
}
defer os.RemoveAll(rootDir)
r, err := New(rootDir, idtools.IDPair{UID: os.Geteuid(), GID: os.Getegid()})
r, err := New(rootDir, idtools.Identity{UID: os.Geteuid(), GID: os.Getegid()})
if err != nil {
t.Fatal(err)
}
@@ -80,7 +80,7 @@ func TestInitializeWithVolumes(t *testing.T) {
}
defer os.RemoveAll(rootDir)
r, err := New(rootDir, idtools.IDPair{UID: os.Geteuid(), GID: os.Getegid()})
r, err := New(rootDir, idtools.Identity{UID: os.Geteuid(), GID: os.Getegid()})
if err != nil {
t.Fatal(err)
}
@@ -90,7 +90,7 @@ func TestInitializeWithVolumes(t *testing.T) {
t.Fatal(err)
}
r, err = New(rootDir, idtools.IDPair{UID: os.Getuid(), GID: os.Getegid()})
r, err = New(rootDir, idtools.Identity{UID: os.Geteuid(), GID: os.Getegid()})
if err != nil {
t.Fatal(err)
}
@@ -112,7 +112,7 @@ func TestCreate(t *testing.T) {
}
defer os.RemoveAll(rootDir)
r, err := New(rootDir, idtools.IDPair{UID: os.Getuid(), GID: os.Getegid()})
r, err := New(rootDir, idtools.Identity{UID: os.Geteuid(), GID: os.Getegid()})
if err != nil {
t.Fatal(err)
}
@@ -149,7 +149,7 @@ func TestCreate(t *testing.T) {
}
}
r, err = New(rootDir, idtools.IDPair{UID: os.Getuid(), GID: os.Getegid()})
r, err = New(rootDir, idtools.Identity{UID: os.Geteuid(), GID: os.Getegid()})
if err != nil {
t.Fatal(err)
}
@@ -186,7 +186,7 @@ func TestCreateWithOpts(t *testing.T) {
}
defer os.RemoveAll(rootDir)
r, err := New(rootDir, idtools.IDPair{UID: os.Getuid(), GID: os.Getegid()})
r, err := New(rootDir, idtools.Identity{UID: os.Geteuid(), GID: os.Getegid()})
if err != nil {
t.Fatal(err)
}
@@ -261,7 +261,7 @@ func TestCreateWithOpts(t *testing.T) {
t.Fatal("expected mount to still be active")
}
r, err = New(rootDir, idtools.IDPair{UID: 0, GID: 0})
r, err = New(rootDir, idtools.Identity{UID: 0, GID: 0})
if err != nil {
t.Fatal(err)
}
@@ -283,7 +283,7 @@ func TestRelaodNoOpts(t *testing.T) {
}
defer os.RemoveAll(rootDir)
r, err := New(rootDir, idtools.IDPair{UID: os.Getuid(), GID: os.Getegid()})
r, err := New(rootDir, idtools.Identity{UID: os.Geteuid(), GID: os.Getegid()})
if err != nil {
t.Fatal(err)
}
@@ -311,7 +311,7 @@ func TestRelaodNoOpts(t *testing.T) {
t.Fatal(err)
}
r, err = New(rootDir, idtools.IDPair{UID: os.Getuid(), GID: os.Getegid()})
r, err = New(rootDir, idtools.Identity{UID: os.Geteuid(), GID: os.Getegid()})
if err != nil {
t.Fatal(err)
}
+1 -1
View File
@@ -95,7 +95,7 @@ func (m *MountPoint) Cleanup() error {
// configured, or creating the source directory if supplied.
// The, optional, checkFun parameter allows doing additional checking
// before creating the source directory on the host.
func (m *MountPoint) Setup(mountLabel string, rootIDs idtools.IDPair, checkFun func(m *MountPoint) error) (path string, err error) {
func (m *MountPoint) Setup(mountLabel string, rootIDs idtools.Identity, checkFun func(m *MountPoint) error) (path string, err error) {
if m.SkipMountpointCreation {
return m.Source, nil
}
@@ -9,7 +9,7 @@ import (
"github.com/pkg/errors"
)
func setupDefaultDriver(store *drivers.Store, root string, rootIDs idtools.IDPair) error {
func setupDefaultDriver(store *drivers.Store, root string, rootIDs idtools.Identity) error {
d, err := local.New(root, rootIDs)
if err != nil {
return errors.Wrap(err, "error setting up default driver")
@@ -7,4 +7,4 @@ import (
"github.com/docker/docker/volume/drivers"
)
func setupDefaultDriver(_ *drivers.Store, _ string, _ idtools.IDPair) error { return nil }
func setupDefaultDriver(_ *drivers.Store, _ string, _ idtools.Identity) error { return nil }
+1 -1
View File
@@ -35,7 +35,7 @@ type VolumesService struct {
}
// NewVolumeService creates a new volume service
func NewVolumeService(root string, pg plugingetter.PluginGetter, rootIDs idtools.IDPair, logger volumeEventLogger) (*VolumesService, error) {
func NewVolumeService(root string, pg plugingetter.PluginGetter, rootIDs idtools.Identity, logger volumeEventLogger) (*VolumesService, error) {
ds := drivers.NewStore(pg)
if err := setupDefaultDriver(ds, root, rootIDs); err != nil {
return nil, err
@@ -25,7 +25,7 @@ func TestLocalVolumeSize(t *testing.T) {
assert.Assert(t, err)
defer os.RemoveAll(dir)
l, err := local.New(dir, idtools.IDPair{UID: os.Getuid(), GID: os.Getegid()})
l, err := local.New(dir, idtools.Identity{UID: os.Getuid(), GID: os.Getegid()})
assert.Assert(t, err)
assert.Assert(t, ds.Register(l, volume.DefaultDriverName))
assert.Assert(t, ds.Register(testutils.NewFakeDriver("fake"), "fake"))