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