daemon/populateVolumes: Support volume subpath
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
parent
349a52b279
commit
cb1af229f2
2 changed files with 39 additions and 30 deletions
|
@ -15,8 +15,6 @@ import (
|
|||
"github.com/docker/docker/api/types/events"
|
||||
mounttypes "github.com/docker/docker/api/types/mount"
|
||||
swarmtypes "github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/docker/volume"
|
||||
volumemounts "github.com/docker/docker/volume/mounts"
|
||||
"github.com/moby/sys/mount"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
|
@ -129,34 +127,11 @@ func (container *Container) NetworkMounts() []Mount {
|
|||
}
|
||||
|
||||
// CopyImagePathContent copies files in destination to the volume.
|
||||
func (container *Container) CopyImagePathContent(v volume.Volume, destination string) error {
|
||||
rootfs, err := container.GetResourcePath(destination)
|
||||
if err != nil {
|
||||
func (container *Container) CopyImagePathContent(volumePath, destination string) error {
|
||||
if err := label.Relabel(volumePath, container.MountLabel, true); err != nil && !errors.Is(err, syscall.ENOTSUP) {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(rootfs); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
id := stringid.GenerateRandomID()
|
||||
path, err := v.Mount(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := v.Unmount(id); err != nil {
|
||||
log.G(context.TODO()).Warnf("error while unmounting volume %s: %v", v.Name(), err)
|
||||
}
|
||||
}()
|
||||
if err := label.Relabel(path, container.MountLabel, true); err != nil && !errors.Is(err, syscall.ENOTSUP) {
|
||||
return err
|
||||
}
|
||||
return copyExistingContents(rootfs, path)
|
||||
return copyExistingContents(destination, volumePath)
|
||||
}
|
||||
|
||||
// ShmResourcePath returns path to shm
|
||||
|
|
|
@ -12,9 +12,12 @@ import (
|
|||
containertypes "github.com/docker/docker/api/types/container"
|
||||
mounttypes "github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/container"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/oci"
|
||||
volumemounts "github.com/docker/docker/volume/mounts"
|
||||
volumeopts "github.com/docker/docker/volume/service/opts"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// createContainerOSSpecificSettings performs host-OS specific container create functionality
|
||||
|
@ -85,10 +88,41 @@ func (daemon *Daemon) populateVolumes(c *container.Container) error {
|
|||
continue
|
||||
}
|
||||
|
||||
log.G(context.TODO()).Debugf("copying image data from %s:%s, to %s", c.ID, mnt.Destination, mnt.Name)
|
||||
if err := c.CopyImagePathContent(mnt.Volume, mnt.Destination); err != nil {
|
||||
if err := daemon.populateVolume(c, mnt); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) populateVolume(c *container.Container, mnt *volumemounts.MountPoint) error {
|
||||
ctrDestPath, err := c.GetResourcePath(mnt.Destination)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(ctrDestPath); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
volumePath, cleanup, err := mnt.Setup(c.MountLabel, daemon.idMapping.RootPair(), nil)
|
||||
if err != nil {
|
||||
if errdefs.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
log.G(context.TODO()).WithError(err).Debugf("can't copy data from %s:%s, to %s", c.ID, mnt.Destination, volumePath)
|
||||
return errors.Wrapf(err, "failed to populate volume")
|
||||
}
|
||||
defer mnt.Cleanup()
|
||||
defer cleanup()
|
||||
|
||||
log.G(context.TODO()).Debugf("copying image data from %s:%s, to %s", c.ID, mnt.Destination, volumePath)
|
||||
if err := c.CopyImagePathContent(volumePath, ctrDestPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue