github.com/adityamillind98/moby@v23.0.0-rc.4+incompatible/daemon/create_unix.go (about)

     1  //go:build !windows
     2  // +build !windows
     3  
     4  package daemon // import "github.com/docker/docker/daemon"
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"os"
    10  	"path/filepath"
    11  
    12  	containertypes "github.com/docker/docker/api/types/container"
    13  	mounttypes "github.com/docker/docker/api/types/mount"
    14  	"github.com/docker/docker/container"
    15  	"github.com/docker/docker/oci"
    16  	"github.com/docker/docker/pkg/stringid"
    17  	volumeopts "github.com/docker/docker/volume/service/opts"
    18  	"github.com/opencontainers/selinux/go-selinux/label"
    19  	"github.com/sirupsen/logrus"
    20  )
    21  
    22  // createContainerOSSpecificSettings performs host-OS specific container create functionality
    23  func (daemon *Daemon) createContainerOSSpecificSettings(container *container.Container, config *containertypes.Config, hostConfig *containertypes.HostConfig) error {
    24  	if err := daemon.Mount(container); err != nil {
    25  		return err
    26  	}
    27  	defer daemon.Unmount(container)
    28  
    29  	rootIDs := daemon.idMapping.RootPair()
    30  	if err := container.SetupWorkingDirectory(rootIDs); err != nil {
    31  		return err
    32  	}
    33  
    34  	// Set the default masked and readonly paths with regard to the host config options if they are not set.
    35  	if hostConfig.MaskedPaths == nil && !hostConfig.Privileged {
    36  		hostConfig.MaskedPaths = oci.DefaultSpec().Linux.MaskedPaths // Set it to the default if nil
    37  		container.HostConfig.MaskedPaths = hostConfig.MaskedPaths
    38  	}
    39  	if hostConfig.ReadonlyPaths == nil && !hostConfig.Privileged {
    40  		hostConfig.ReadonlyPaths = oci.DefaultSpec().Linux.ReadonlyPaths // Set it to the default if nil
    41  		container.HostConfig.ReadonlyPaths = hostConfig.ReadonlyPaths
    42  	}
    43  
    44  	for spec := range config.Volumes {
    45  		name := stringid.GenerateRandomID()
    46  		destination := filepath.Clean(spec)
    47  
    48  		// Skip volumes for which we already have something mounted on that
    49  		// destination because of a --volume-from.
    50  		if container.HasMountFor(destination) {
    51  			logrus.WithField("container", container.ID).WithField("destination", spec).Debug("mountpoint already exists, skipping anonymous volume")
    52  			// Not an error, this could easily have come from the image config.
    53  			continue
    54  		}
    55  		path, err := container.GetResourcePath(destination)
    56  		if err != nil {
    57  			return err
    58  		}
    59  
    60  		stat, err := os.Stat(path)
    61  		if err == nil && !stat.IsDir() {
    62  			return fmt.Errorf("cannot mount volume over existing file, file exists %s", path)
    63  		}
    64  
    65  		v, err := daemon.volumes.Create(context.TODO(), name, hostConfig.VolumeDriver, volumeopts.WithCreateReference(container.ID))
    66  		if err != nil {
    67  			return err
    68  		}
    69  
    70  		if err := label.Relabel(v.Mountpoint, container.MountLabel, true); err != nil {
    71  			return err
    72  		}
    73  
    74  		container.AddMountPointWithVolume(destination, &volumeWrapper{v: v, s: daemon.volumes}, true)
    75  	}
    76  	return daemon.populateVolumes(container)
    77  }
    78  
    79  // populateVolumes copies data from the container's rootfs into the volume for non-binds.
    80  // this is only called when the container is created.
    81  func (daemon *Daemon) populateVolumes(c *container.Container) error {
    82  	for _, mnt := range c.MountPoints {
    83  		if mnt.Volume == nil {
    84  			continue
    85  		}
    86  
    87  		if mnt.Type != mounttypes.TypeVolume || !mnt.CopyData {
    88  			continue
    89  		}
    90  
    91  		logrus.Debugf("copying image data from %s:%s, to %s", c.ID, mnt.Destination, mnt.Name)
    92  		if err := c.CopyImagePathContent(mnt.Volume, mnt.Destination); err != nil {
    93  			return err
    94  		}
    95  	}
    96  	return nil
    97  }