create_unix.go 2.2 KB

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