Files
moby/daemon/create_unix.go
Rob Murray 96b8f9c8ca Daemon.createContainerOSSpecificSettings - remove redundant param
Also:
- remove the hostConfig param from Daemon.createContainerVolumesOS.
- rename var container -> ctr

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-11-16 18:25:42 +00:00

134 lines
4.1 KiB
Go

//go:build !windows
package daemon
import (
"context"
"fmt"
"os"
"path/filepath"
cerrdefs "github.com/containerd/errdefs"
"github.com/containerd/log"
containertypes "github.com/moby/moby/api/types/container"
mounttypes "github.com/moby/moby/api/types/mount"
"github.com/moby/moby/v2/daemon/container"
"github.com/moby/moby/v2/daemon/internal/idtools"
"github.com/moby/moby/v2/daemon/pkg/oci"
volumemounts "github.com/moby/moby/v2/daemon/volume/mounts"
volumeopts "github.com/moby/moby/v2/daemon/volume/service/opts"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
)
// createContainerOSSpecificSettings performs host-OS specific container create functionality
func (daemon *Daemon) createContainerOSSpecificSettings(ctx context.Context, ctr *container.Container) error {
// Set the default masked and readonly paths with regard to the host config options if they are not set.
if ctr.HostConfig.MaskedPaths == nil && !ctr.HostConfig.Privileged {
ctr.HostConfig.MaskedPaths = oci.DefaultSpec().Linux.MaskedPaths // Set it to the default if nil
}
if ctr.HostConfig.ReadonlyPaths == nil && !ctr.HostConfig.Privileged {
ctr.HostConfig.ReadonlyPaths = oci.DefaultSpec().Linux.ReadonlyPaths // Set it to the default if nil
}
return nil
}
// createContainerVolumesOS performs host-OS specific volume creation
func (daemon *Daemon) createContainerVolumesOS(ctx context.Context, ctr *container.Container, config *containertypes.Config) error {
if err := daemon.Mount(ctr); err != nil {
return err
}
defer daemon.Unmount(ctr)
if err := ctr.SetupWorkingDirectory(daemon.idMapping.RootPair()); err != nil {
return err
}
for spec := range config.Volumes {
destination := filepath.Clean(spec)
// Skip volumes for which we already have something mounted on that
// destination because of a --volume-from.
if ctr.HasMountFor(destination) {
log.G(ctx).WithField("container", ctr.ID).WithField("destination", spec).Debug("mountpoint already exists, skipping anonymous volume")
// Not an error, this could easily have come from the image config.
continue
}
path, err := ctr.GetResourcePath(destination)
if err != nil {
return err
}
stat, err := os.Stat(path)
if err == nil && !stat.IsDir() {
return fmt.Errorf("cannot mount volume over existing file, file exists %s", path)
}
v, err := daemon.volumes.Create(context.TODO(), "", ctr.HostConfig.VolumeDriver, volumeopts.WithCreateReference(ctr.ID))
if err != nil {
return err
}
if err := label.Relabel(v.Mountpoint, ctr.MountLabel, true); err != nil {
return err
}
ctr.AddMountPointWithVolume(destination, &volumeWrapper{v: v, s: daemon.volumes}, true)
}
return daemon.populateVolumes(ctx, ctr)
}
// populateVolumes copies data from the container's rootfs into the volume for non-binds.
// this is only called when the container is created.
func (daemon *Daemon) populateVolumes(ctx context.Context, c *container.Container) error {
for _, mnt := range c.MountPoints {
if mnt.Volume == nil {
continue
}
if mnt.Type != mounttypes.TypeVolume || !mnt.CopyData {
continue
}
if err := daemon.populateVolume(ctx, c, mnt); err != nil {
return err
}
}
return nil
}
func (daemon *Daemon) populateVolume(ctx context.Context, 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
}
uid, gid := daemon.idMapping.RootPair()
volumePath, cleanup, err := mnt.Setup(ctx, c.MountLabel, idtools.Identity{UID: uid, GID: gid}, nil)
if err != nil {
if cerrdefs.IsNotFound(err) {
return nil
}
log.G(ctx).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 func() {
ctx := context.WithoutCancel(ctx)
_ = cleanup(ctx)
_ = mnt.Cleanup(ctx)
}()
log.G(ctx).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
}