create_unix.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // +build !windows
  2. package daemon
  3. import (
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. "github.com/Sirupsen/logrus"
  8. containertypes "github.com/docker/docker/api/types/container"
  9. mounttypes "github.com/docker/docker/api/types/mount"
  10. "github.com/docker/docker/container"
  11. "github.com/docker/docker/pkg/stringid"
  12. "github.com/opencontainers/runc/libcontainer/label"
  13. )
  14. // createContainerPlatformSpecificSettings performs platform specific container create functionality
  15. func (daemon *Daemon) createContainerPlatformSpecificSettings(container *container.Container, config *containertypes.Config, hostConfig *containertypes.HostConfig) error {
  16. if err := daemon.Mount(container); err != nil {
  17. return err
  18. }
  19. defer daemon.Unmount(container)
  20. rootUID, rootGID := daemon.GetRemappedUIDGID()
  21. if err := container.SetupWorkingDirectory(rootUID, rootGID); err != nil {
  22. return err
  23. }
  24. for spec := range config.Volumes {
  25. name := stringid.GenerateNonCryptoID()
  26. destination := filepath.Clean(spec)
  27. // Skip volumes for which we already have something mounted on that
  28. // destination because of a --volume-from.
  29. if container.IsDestinationMounted(destination) {
  30. continue
  31. }
  32. path, err := container.GetResourcePath(destination)
  33. if err != nil {
  34. return err
  35. }
  36. stat, err := os.Stat(path)
  37. if err == nil && !stat.IsDir() {
  38. return fmt.Errorf("cannot mount volume over existing file, file exists %s", path)
  39. }
  40. v, err := daemon.volumes.CreateWithRef(name, hostConfig.VolumeDriver, container.ID, nil, nil)
  41. if err != nil {
  42. return err
  43. }
  44. if err := label.Relabel(v.Path(), container.MountLabel, true); err != nil {
  45. return err
  46. }
  47. container.AddMountPointWithVolume(destination, v, true)
  48. }
  49. return daemon.populateVolumes(container)
  50. }
  51. // populateVolumes copies data from the container's rootfs into the volume for non-binds.
  52. // this is only called when the container is created.
  53. func (daemon *Daemon) populateVolumes(c *container.Container) error {
  54. for _, mnt := range c.MountPoints {
  55. if mnt.Volume == nil {
  56. continue
  57. }
  58. if mnt.Type != mounttypes.TypeVolume || !mnt.CopyData {
  59. continue
  60. }
  61. logrus.Debugf("copying image data from %s:%s, to %s", c.ID, mnt.Destination, mnt.Name)
  62. if err := c.CopyImagePathContent(mnt.Volume, mnt.Destination); err != nil {
  63. return err
  64. }
  65. }
  66. return nil
  67. }