1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- //go:build !windows
- // +build !windows
- package daemon // import "github.com/docker/docker/daemon"
- import (
- "context"
- "fmt"
- "os"
- "path/filepath"
- 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/oci"
- volumeopts "github.com/docker/docker/volume/service/opts"
- "github.com/opencontainers/selinux/go-selinux/label"
- "github.com/sirupsen/logrus"
- )
- // createContainerOSSpecificSettings performs host-OS specific container create functionality
- func (daemon *Daemon) createContainerOSSpecificSettings(container *container.Container, config *containertypes.Config, hostConfig *containertypes.HostConfig) error {
- if err := daemon.Mount(container); err != nil {
- return err
- }
- defer daemon.Unmount(container)
- rootIDs := daemon.idMapping.RootPair()
- if err := container.SetupWorkingDirectory(rootIDs); err != nil {
- return err
- }
- // Set the default masked and readonly paths with regard to the host config options if they are not set.
- if hostConfig.MaskedPaths == nil && !hostConfig.Privileged {
- hostConfig.MaskedPaths = oci.DefaultSpec().Linux.MaskedPaths // Set it to the default if nil
- container.HostConfig.MaskedPaths = hostConfig.MaskedPaths
- }
- if hostConfig.ReadonlyPaths == nil && !hostConfig.Privileged {
- hostConfig.ReadonlyPaths = oci.DefaultSpec().Linux.ReadonlyPaths // Set it to the default if nil
- container.HostConfig.ReadonlyPaths = hostConfig.ReadonlyPaths
- }
- 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 container.HasMountFor(destination) {
- logrus.WithField("container", container.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 := container.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(), "", hostConfig.VolumeDriver, volumeopts.WithCreateReference(container.ID))
- if err != nil {
- return err
- }
- if err := label.Relabel(v.Mountpoint, container.MountLabel, true); err != nil {
- return err
- }
- container.AddMountPointWithVolume(destination, &volumeWrapper{v: v, s: daemon.volumes}, true)
- }
- return daemon.populateVolumes(container)
- }
- // 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(c *container.Container) error {
- for _, mnt := range c.MountPoints {
- if mnt.Volume == nil {
- continue
- }
- if mnt.Type != mounttypes.TypeVolume || !mnt.CopyData {
- continue
- }
- logrus.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 {
- return err
- }
- }
- return nil
- }
|