create.go 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package daemon
  2. import (
  3. "github.com/docker/docker/engine"
  4. "github.com/docker/docker/graph"
  5. "github.com/docker/docker/pkg/parsers"
  6. "github.com/docker/docker/runconfig"
  7. )
  8. func (daemon *Daemon) ContainerCreate(job *engine.Job) engine.Status {
  9. var name string
  10. if len(job.Args) == 1 {
  11. name = job.Args[0]
  12. } else if len(job.Args) > 1 {
  13. return job.Errorf("Usage: %s", job.Name)
  14. }
  15. config := runconfig.ContainerConfigFromJob(job)
  16. if config.Memory != 0 && config.Memory < 524288 {
  17. return job.Errorf("Minimum memory limit allowed is 512k")
  18. }
  19. if config.Memory > 0 && !daemon.SystemConfig().MemoryLimit {
  20. job.Errorf("Your kernel does not support memory limit capabilities. Limitation discarded.\n")
  21. config.Memory = 0
  22. }
  23. if config.Memory > 0 && !daemon.SystemConfig().SwapLimit {
  24. job.Errorf("Your kernel does not support swap limit capabilities. Limitation discarded.\n")
  25. config.MemorySwap = -1
  26. }
  27. container, buildWarnings, err := daemon.Create(config, name)
  28. if err != nil {
  29. if daemon.Graph().IsNotExist(err) {
  30. _, tag := parsers.ParseRepositoryTag(config.Image)
  31. if tag == "" {
  32. tag = graph.DEFAULTTAG
  33. }
  34. return job.Errorf("No such image: %s (tag: %s)", config.Image, tag)
  35. }
  36. return job.Error(err)
  37. }
  38. if !container.Config.NetworkDisabled && daemon.SystemConfig().IPv4ForwardingDisabled {
  39. job.Errorf("IPv4 forwarding is disabled.\n")
  40. }
  41. container.LogEvent("create")
  42. // FIXME: this is necessary because daemon.Create might return a nil container
  43. // with a non-nil error. This should not happen! Once it's fixed we
  44. // can remove this workaround.
  45. if container != nil {
  46. job.Printf("%s\n", container.ID)
  47. }
  48. for _, warning := range buildWarnings {
  49. job.Errorf("%s\n", warning)
  50. }
  51. return engine.StatusOK
  52. }
  53. // Create creates a new container from the given configuration with a given name.
  54. func (daemon *Daemon) Create(config *runconfig.Config, name string) (*Container, []string, error) {
  55. var (
  56. container *Container
  57. warnings []string
  58. )
  59. img, err := daemon.repositories.LookupImage(config.Image)
  60. if err != nil {
  61. return nil, nil, err
  62. }
  63. if err := img.CheckDepth(); err != nil {
  64. return nil, nil, err
  65. }
  66. if warnings, err = daemon.mergeAndVerifyConfig(config, img); err != nil {
  67. return nil, nil, err
  68. }
  69. if container, err = daemon.newContainer(name, config, img); err != nil {
  70. return nil, nil, err
  71. }
  72. if err := daemon.createRootfs(container, img); err != nil {
  73. return nil, nil, err
  74. }
  75. if err := container.ToDisk(); err != nil {
  76. return nil, nil, err
  77. }
  78. if err := daemon.Register(container); err != nil {
  79. return nil, nil, err
  80. }
  81. return container, warnings, nil
  82. }