create.go 3.9 KB

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