Skip to content

Commit

Permalink
copy: allow to mount /dev /tmp/ /proc
Browse files Browse the repository at this point in the history
The /dev/ /tmp /proc are default mount point from oci spec. They are not
in the container mount points. When we pass the /dev/terminal-log as
dest, it will mount after the /dev, which handed by runC in the special
namespace. But when we try to mount for copy, we don't have /dev folder
or sub folder, we need to create parent folder for the target or empty
file.

Signed-off-by: Wei Fu <fuweid89@gmail.com>
  • Loading branch information
fuweid authored and ZYecho committed Jun 4, 2019
1 parent 0417d69 commit 86433c9
Showing 1 changed file with 30 additions and 22 deletions.
52 changes: 30 additions & 22 deletions daemon/mgr/container_copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/chrootarchive"
"github.com/docker/docker/pkg/fileutils"
"github.com/docker/docker/pkg/mount"
"github.com/go-openapi/strfmt"
pkgerrors "github.com/pkg/errors"
Expand All @@ -30,28 +31,28 @@ func (mgr *ContainerManager) StatPath(ctx context.Context, name, path string) (s
defer c.Unlock()

if c.State.Dead {
return nil, pkgerrors.Errorf("container has been deleted %s", c.ID)
return nil, pkgerrors.Errorf("container(%s) has been deleted", c.ID)
}

running := c.IsRunningOrPaused()
err = mgr.Mount(ctx, c, false)
if err != nil {
return nil, err
return nil, pkgerrors.Wrapf(err, "failed to mount cid(%s)", c.ID)
}

defer mgr.Unmount(ctx, c, false, !running)

if !running {
err = mgr.attachVolumes(ctx, c)
if err != nil {
return nil, err
return nil, pkgerrors.Wrapf(err, "failed to attachVolumes cid(%s)", c.ID)
}
defer mgr.detachVolumes(ctx, c, false)
}

err = c.mountVolumes(!running)
err = c.mountVolumes()
if err != nil {
return nil, err
return nil, pkgerrors.Wrapf(err, "failed to mountVolumes cid(%s)", c.ID)
}
defer c.unmountVolumes()

Expand Down Expand Up @@ -85,13 +86,13 @@ func (mgr *ContainerManager) ArchivePath(ctx context.Context, name, path string)
}()

if c.State.Dead {
return nil, nil, pkgerrors.Errorf("container has been deleted %s", c.ID)
return nil, nil, pkgerrors.Errorf("container(%s) has been deleted", c.ID)
}

running := c.IsRunningOrPaused()
err = mgr.Mount(ctx, c, false)
if err != nil {
return nil, nil, err
return nil, nil, pkgerrors.Wrapf(err, "failed to mount cid(%s)", c.ID)
}
defer func() {
if err0 != nil {
Expand All @@ -102,7 +103,7 @@ func (mgr *ContainerManager) ArchivePath(ctx context.Context, name, path string)
if !running {
err = mgr.attachVolumes(ctx, c)
if err != nil {
return nil, nil, err
return nil, nil, pkgerrors.Wrapf(err, "failed to attachVolumes cid(%s)", c.ID)
}
defer func() {
if err0 != nil {
Expand All @@ -111,9 +112,9 @@ func (mgr *ContainerManager) ArchivePath(ctx context.Context, name, path string)
}()
}

err = c.mountVolumes(!running)
err = c.mountVolumes()
if err != nil {
return nil, nil, err
return nil, nil, pkgerrors.Wrapf(err, "failed to mountVolumes cid(%s)", c.ID)
}
defer func() {
if err0 != nil {
Expand Down Expand Up @@ -169,27 +170,27 @@ func (mgr *ContainerManager) ExtractToDir(ctx context.Context, name, path string
defer c.Unlock()

if c.State.Dead {
return pkgerrors.Errorf("container has been deleted %s", c.ID)
return pkgerrors.Errorf("container(%s) has been deleted", c.ID)
}

running := c.IsRunningOrPaused()
err = mgr.Mount(ctx, c, false)
if err != nil {
return err
return pkgerrors.Wrapf(err, "failed to mount cid(%s)", c.ID)
}
defer mgr.Unmount(ctx, c, false, !running)

if !running {
err = mgr.attachVolumes(ctx, c)
if err != nil {
return err
return pkgerrors.Wrapf(err, "failed to attachVolumes cid(%s)", c.ID)
}
defer mgr.detachVolumes(ctx, c, false)
}

err = c.mountVolumes(!running)
err = c.mountVolumes()
if err != nil {
return err
return pkgerrors.Wrapf(err, "failed to mountVolumes cid(%s)", c.ID)
}
defer c.unmountVolumes()

Expand Down Expand Up @@ -243,14 +244,16 @@ func (c *Container) getResolvedPath(path string) (resolvedPath, absPath string)
return resolvedPath, absPath
}

func (c *Container) mountVolumes(created bool) (err0 error) {
func (c *Container) mountVolumes() (err0 error) {
rollbackMounts := make([]string, 0, len(c.Mounts))

defer func() {
if err0 != nil {
for _, dest := range rollbackMounts {
if err := mount.Unmount(dest); err != nil {
logrus.Warnf("[rollback] failed to unmount(%s), err(%v)", dest, err)
logrus.Warnf("[mountVolumes:rollback] failed to unmount(%s), err(%v)", dest, err)
} else {
logrus.Debugf("[mountVolumes:rollback] unmount(%s)", dest)
}
}
}
Expand All @@ -259,15 +262,20 @@ func (c *Container) mountVolumes(created bool) (err0 error) {
for _, m := range c.Mounts {
dest, _ := c.getResolvedPath(m.Destination)

_, err := os.Stat(m.Source)
logrus.Debugf("try to mount volume(source %s -> dest %s", m.Source, dest)

stat, err := os.Stat(m.Source)
if err != nil {
return err
}

if created {
if e := os.MkdirAll(dest, 0755); e != nil {
return e
}
// /dev /proc /tmp is mounted by default oci spec. Those mount
// points are mounted by runC. In k8s, the daemonset will mount
// log into /dev/termination-log. Before mount it, we need to
// create folder or empty file for the target. It will not
// impact the running container.
if err = fileutils.CreateIfNotExists(dest, stat.IsDir()); err != nil {
return err
}

writeMode := "ro"
Expand Down

0 comments on commit 86433c9

Please sign in to comment.