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 }