init.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // DEPRECATION NOTICE. PLEASE DO NOT ADD ANYTHING TO THIS FILE.
  2. //
  3. // For additional commments see server/server.go
  4. //
  5. package server
  6. import (
  7. "fmt"
  8. "log"
  9. "os"
  10. gosignal "os/signal"
  11. "sync/atomic"
  12. "syscall"
  13. "github.com/docker/docker/daemon"
  14. "github.com/docker/docker/daemonconfig"
  15. "github.com/docker/docker/engine"
  16. "github.com/docker/docker/utils"
  17. )
  18. func (srv *Server) handlerWrap(h engine.Handler) engine.Handler {
  19. return func(job *engine.Job) engine.Status {
  20. if !srv.IsRunning() {
  21. return job.Errorf("Server is not running")
  22. }
  23. srv.tasks.Add(1)
  24. defer srv.tasks.Done()
  25. return h(job)
  26. }
  27. }
  28. func InitPidfile(job *engine.Job) engine.Status {
  29. if len(job.Args) == 0 {
  30. return job.Error(fmt.Errorf("no pidfile provided to initialize"))
  31. }
  32. job.Logf("Creating pidfile")
  33. if err := utils.CreatePidFile(job.Args[0]); err != nil {
  34. return job.Error(err)
  35. }
  36. return engine.StatusOK
  37. }
  38. // jobInitApi runs the remote api server `srv` as a daemon,
  39. // Only one api server can run at the same time - this is enforced by a pidfile.
  40. // The signals SIGINT, SIGQUIT and SIGTERM are intercepted for cleanup.
  41. func InitServer(job *engine.Job) engine.Status {
  42. job.Logf("Creating server")
  43. srv, err := NewServer(job.Eng, daemonconfig.ConfigFromJob(job))
  44. if err != nil {
  45. return job.Error(err)
  46. }
  47. job.Logf("Setting up signal traps")
  48. c := make(chan os.Signal, 1)
  49. signals := []os.Signal{os.Interrupt, syscall.SIGTERM}
  50. if os.Getenv("DEBUG") == "" {
  51. signals = append(signals, syscall.SIGQUIT)
  52. }
  53. gosignal.Notify(c, signals...)
  54. go func() {
  55. interruptCount := uint32(0)
  56. for sig := range c {
  57. go func(sig os.Signal) {
  58. log.Printf("Received signal '%v', starting shutdown of docker...\n", sig)
  59. switch sig {
  60. case os.Interrupt, syscall.SIGTERM:
  61. // If the user really wants to interrupt, let him do so.
  62. if atomic.LoadUint32(&interruptCount) < 3 {
  63. atomic.AddUint32(&interruptCount, 1)
  64. // Initiate the cleanup only once
  65. if atomic.LoadUint32(&interruptCount) == 1 {
  66. utils.RemovePidFile(srv.daemon.Config().Pidfile)
  67. srv.Close()
  68. } else {
  69. return
  70. }
  71. } else {
  72. log.Printf("Force shutdown of docker, interrupting cleanup\n")
  73. }
  74. case syscall.SIGQUIT:
  75. }
  76. os.Exit(128 + int(sig.(syscall.Signal)))
  77. }(sig)
  78. }
  79. }()
  80. job.Eng.Hack_SetGlobalVar("httpapi.server", srv)
  81. job.Eng.Hack_SetGlobalVar("httpapi.daemon", srv.daemon)
  82. for name, handler := range map[string]engine.Handler{
  83. "tag": srv.ImageTag, // FIXME merge with "image_tag"
  84. "info": srv.DockerInfo,
  85. "image_export": srv.ImageExport,
  86. "images": srv.Images,
  87. "history": srv.ImageHistory,
  88. "viz": srv.ImagesViz,
  89. "log": srv.Log,
  90. "load": srv.ImageLoad,
  91. "build": srv.Build,
  92. "pull": srv.ImagePull,
  93. "import": srv.ImageImport,
  94. "image_delete": srv.ImageDelete,
  95. "events": srv.Events,
  96. "push": srv.ImagePush,
  97. "containers": srv.Containers,
  98. } {
  99. if err := job.Eng.Register(name, srv.handlerWrap(handler)); err != nil {
  100. return job.Error(err)
  101. }
  102. }
  103. // Install image-related commands from the image subsystem.
  104. // See `graph/service.go`
  105. if err := srv.daemon.Repositories().Install(job.Eng); err != nil {
  106. return job.Error(err)
  107. }
  108. // Install daemon-related commands from the daemon subsystem.
  109. // See `daemon/`
  110. if err := srv.daemon.Install(job.Eng); err != nil {
  111. return job.Error(err)
  112. }
  113. srv.SetRunning(true)
  114. return engine.StatusOK
  115. }
  116. func NewServer(eng *engine.Engine, config *daemonconfig.Config) (*Server, error) {
  117. daemon, err := daemon.NewDaemon(config, eng)
  118. if err != nil {
  119. return nil, err
  120. }
  121. srv := &Server{
  122. Eng: eng,
  123. daemon: daemon,
  124. pullingPool: make(map[string]chan struct{}),
  125. pushingPool: make(map[string]chan struct{}),
  126. events: make([]utils.JSONMessage, 0, 64), //only keeps the 64 last events
  127. eventPublisher: utils.NewJSONMessagePublisher(),
  128. }
  129. daemon.SetServer(srv)
  130. return srv, nil
  131. }