From cb1af229f207913ddf998db7b0878ea4b2e134a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= Date: Fri, 9 Jun 2023 20:19:34 +0200 Subject: [PATCH] daemon/populateVolumes: Support volume subpath MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paweł Gronowski --- container/container_unix.go | 31 +++--------------------------- daemon/create_unix.go | 38 +++++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/container/container_unix.go b/container/container_unix.go index fc35f7165a..6da71790c7 100644 --- a/container/container_unix.go +++ b/container/container_unix.go @@ -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 diff --git a/daemon/create_unix.go b/daemon/create_unix.go index 228d4a62e9..1d17cf5f95 100644 --- a/daemon/create_unix.go +++ b/daemon/create_unix.go @@ -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 +}