create.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package daemon
  2. import (
  3. "strings"
  4. "github.com/Sirupsen/logrus"
  5. "github.com/docker/docker/api/types"
  6. derr "github.com/docker/docker/errors"
  7. "github.com/docker/docker/graph/tags"
  8. "github.com/docker/docker/image"
  9. "github.com/docker/docker/pkg/parsers"
  10. "github.com/docker/docker/pkg/stringid"
  11. "github.com/docker/docker/runconfig"
  12. "github.com/opencontainers/runc/libcontainer/label"
  13. )
  14. // ContainerCreate takes configs and creates a container.
  15. func (daemon *Daemon) ContainerCreate(name string, config *runconfig.Config, hostConfig *runconfig.HostConfig, adjustCPUShares bool) (*Container, []string, error) {
  16. if config == nil {
  17. return nil, nil, derr.ErrorCodeEmptyConfig
  18. }
  19. warnings, err := daemon.verifyContainerSettings(hostConfig, config)
  20. if err != nil {
  21. return nil, warnings, err
  22. }
  23. daemon.adaptContainerSettings(hostConfig, adjustCPUShares)
  24. container, buildWarnings, err := daemon.Create(config, hostConfig, name)
  25. if err != nil {
  26. if daemon.Graph().IsNotExist(err, config.Image) {
  27. if strings.Contains(config.Image, "@") {
  28. return nil, warnings, derr.ErrorCodeNoSuchImageHash.WithArgs(config.Image)
  29. }
  30. img, tag := parsers.ParseRepositoryTag(config.Image)
  31. if tag == "" {
  32. tag = tags.DefaultTag
  33. }
  34. return nil, warnings, derr.ErrorCodeNoSuchImageTag.WithArgs(img, tag)
  35. }
  36. return nil, warnings, err
  37. }
  38. warnings = append(warnings, buildWarnings...)
  39. return container, warnings, nil
  40. }
  41. // Create creates a new container from the given configuration with a given name.
  42. func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.HostConfig, name string) (retC *Container, retS []string, retErr error) {
  43. var (
  44. container *Container
  45. warnings []string
  46. img *image.Image
  47. imgID string
  48. err error
  49. )
  50. if config.Image != "" {
  51. img, err = daemon.repositories.LookupImage(config.Image)
  52. if err != nil {
  53. return nil, nil, err
  54. }
  55. if err = daemon.graph.CheckDepth(img); err != nil {
  56. return nil, nil, err
  57. }
  58. imgID = img.ID
  59. }
  60. if err := daemon.mergeAndVerifyConfig(config, img); err != nil {
  61. return nil, nil, err
  62. }
  63. if hostConfig == nil {
  64. hostConfig = &runconfig.HostConfig{}
  65. }
  66. if hostConfig.SecurityOpt == nil {
  67. hostConfig.SecurityOpt, err = daemon.generateSecurityOpt(hostConfig.IpcMode, hostConfig.PidMode)
  68. if err != nil {
  69. return nil, nil, err
  70. }
  71. }
  72. if container, err = daemon.newContainer(name, config, imgID); err != nil {
  73. return nil, nil, err
  74. }
  75. defer func() {
  76. if retErr != nil {
  77. if err := daemon.rm(container, false); err != nil {
  78. logrus.Errorf("Clean up Error! Cannot destroy container %s: %v", container.ID, err)
  79. }
  80. }
  81. }()
  82. if err := daemon.Register(container); err != nil {
  83. return nil, nil, err
  84. }
  85. if err := daemon.createRootfs(container); err != nil {
  86. return nil, nil, err
  87. }
  88. if err := daemon.setHostConfig(container, hostConfig); err != nil {
  89. return nil, nil, err
  90. }
  91. defer func() {
  92. if retErr != nil {
  93. if err := container.removeMountPoints(true); err != nil {
  94. logrus.Error(err)
  95. }
  96. }
  97. }()
  98. if err := container.Mount(); err != nil {
  99. return nil, nil, err
  100. }
  101. defer container.Unmount()
  102. if err := createContainerPlatformSpecificSettings(container, config, hostConfig, img); err != nil {
  103. return nil, nil, err
  104. }
  105. if err := container.toDiskLocking(); err != nil {
  106. logrus.Errorf("Error saving new container to disk: %v", err)
  107. return nil, nil, err
  108. }
  109. container.logEvent("create")
  110. return container, warnings, nil
  111. }
  112. func (daemon *Daemon) generateSecurityOpt(ipcMode runconfig.IpcMode, pidMode runconfig.PidMode) ([]string, error) {
  113. if ipcMode.IsHost() || pidMode.IsHost() {
  114. return label.DisableSecOpt(), nil
  115. }
  116. if ipcContainer := ipcMode.Container(); ipcContainer != "" {
  117. c, err := daemon.Get(ipcContainer)
  118. if err != nil {
  119. return nil, err
  120. }
  121. return label.DupSecOpt(c.ProcessLabel), nil
  122. }
  123. return nil, nil
  124. }
  125. // VolumeCreate creates a volume with the specified name, driver, and opts
  126. // This is called directly from the remote API
  127. func (daemon *Daemon) VolumeCreate(name, driverName string, opts map[string]string) (*types.Volume, error) {
  128. if name == "" {
  129. name = stringid.GenerateNonCryptoID()
  130. }
  131. v, err := daemon.volumes.Create(name, driverName, opts)
  132. if err != nil {
  133. return nil, err
  134. }
  135. return volumeToAPIType(v), nil
  136. }