create_unix.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // +build !windows
  2. package daemon
  3. import (
  4. "os"
  5. "path/filepath"
  6. "github.com/Sirupsen/logrus"
  7. "github.com/docker/docker/container"
  8. derr "github.com/docker/docker/errors"
  9. "github.com/docker/docker/image"
  10. "github.com/docker/docker/pkg/stringid"
  11. "github.com/docker/docker/volume"
  12. containertypes "github.com/docker/engine-api/types/container"
  13. "github.com/opencontainers/runc/libcontainer/label"
  14. )
  15. // createContainerPlatformSpecificSettings performs platform specific container create functionality
  16. func (daemon *Daemon) createContainerPlatformSpecificSettings(container *container.Container, config *containertypes.Config, hostConfig *containertypes.HostConfig, img *image.Image) error {
  17. if err := daemon.Mount(container); err != nil {
  18. return err
  19. }
  20. defer daemon.Unmount(container)
  21. for spec := range config.Volumes {
  22. name := stringid.GenerateNonCryptoID()
  23. destination := filepath.Clean(spec)
  24. // Skip volumes for which we already have something mounted on that
  25. // destination because of a --volume-from.
  26. if container.IsDestinationMounted(destination) {
  27. continue
  28. }
  29. path, err := container.GetResourcePath(destination)
  30. if err != nil {
  31. return err
  32. }
  33. stat, err := os.Stat(path)
  34. if err == nil && !stat.IsDir() {
  35. return derr.ErrorCodeMountOverFile.WithArgs(path)
  36. }
  37. volumeDriver := hostConfig.VolumeDriver
  38. if destination != "" && img != nil {
  39. if _, ok := img.ContainerConfig.Volumes[destination]; ok {
  40. // check for whether bind is not specified and then set to local
  41. if _, ok := container.MountPoints[destination]; !ok {
  42. volumeDriver = volume.DefaultDriverName
  43. }
  44. }
  45. }
  46. v, err := daemon.volumes.CreateWithRef(name, volumeDriver, container.ID, nil)
  47. if err != nil {
  48. return err
  49. }
  50. if err := label.Relabel(v.Path(), container.MountLabel, true); err != nil {
  51. return err
  52. }
  53. container.AddMountPointWithVolume(destination, v, true)
  54. }
  55. return daemon.populateVolumes(container)
  56. }
  57. // populateVolumes copies data from the container's rootfs into the volume for non-binds.
  58. // this is only called when the container is created.
  59. func (daemon *Daemon) populateVolumes(c *container.Container) error {
  60. for _, mnt := range c.MountPoints {
  61. // skip binds and volumes referenced by other containers (ie, volumes-from)
  62. if mnt.Driver == "" || mnt.Volume == nil || len(daemon.volumes.Refs(mnt.Volume)) > 1 {
  63. continue
  64. }
  65. logrus.Debugf("copying image data from %s:%s, to %s", c.ID, mnt.Destination, mnt.Name)
  66. if err := c.CopyImagePathContent(mnt.Volume, mnt.Destination); err != nil {
  67. return err
  68. }
  69. }
  70. return nil
  71. }