daemon.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package server
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "runtime"
  6. "strconv"
  7. "strings"
  8. "time"
  9. "github.com/Sirupsen/logrus"
  10. "github.com/docker/docker/api"
  11. "github.com/docker/docker/api/types"
  12. "github.com/docker/docker/autogen/dockerversion"
  13. "github.com/docker/docker/context"
  14. "github.com/docker/docker/pkg/ioutils"
  15. "github.com/docker/docker/pkg/jsonmessage"
  16. "github.com/docker/docker/pkg/parsers/filters"
  17. "github.com/docker/docker/pkg/parsers/kernel"
  18. "github.com/docker/docker/utils"
  19. )
  20. func (s *Server) getVersion(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
  21. v := &types.Version{
  22. Version: dockerversion.VERSION,
  23. APIVersion: api.Version,
  24. GitCommit: dockerversion.GITCOMMIT,
  25. GoVersion: runtime.Version(),
  26. Os: runtime.GOOS,
  27. Arch: runtime.GOARCH,
  28. BuildTime: dockerversion.BUILDTIME,
  29. }
  30. version := ctx.Version()
  31. if version.GreaterThanOrEqualTo("1.19") {
  32. v.Experimental = utils.ExperimentalBuild()
  33. }
  34. if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
  35. v.KernelVersion = kernelVersion.String()
  36. }
  37. return writeJSON(w, http.StatusOK, v)
  38. }
  39. func (s *Server) getInfo(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
  40. info, err := s.daemon.SystemInfo(ctx)
  41. if err != nil {
  42. return err
  43. }
  44. return writeJSON(w, http.StatusOK, info)
  45. }
  46. func (s *Server) getEvents(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
  47. if err := parseForm(r); err != nil {
  48. return err
  49. }
  50. var since int64 = -1
  51. if r.Form.Get("since") != "" {
  52. s, err := strconv.ParseInt(r.Form.Get("since"), 10, 64)
  53. if err != nil {
  54. return err
  55. }
  56. since = s
  57. }
  58. var until int64 = -1
  59. if r.Form.Get("until") != "" {
  60. u, err := strconv.ParseInt(r.Form.Get("until"), 10, 64)
  61. if err != nil {
  62. return err
  63. }
  64. until = u
  65. }
  66. timer := time.NewTimer(0)
  67. timer.Stop()
  68. if until > 0 {
  69. dur := time.Unix(until, 0).Sub(time.Now())
  70. timer = time.NewTimer(dur)
  71. }
  72. ef, err := filters.FromParam(r.Form.Get("filters"))
  73. if err != nil {
  74. return err
  75. }
  76. isFiltered := func(field string, filter []string) bool {
  77. if len(field) == 0 {
  78. return false
  79. }
  80. if len(filter) == 0 {
  81. return false
  82. }
  83. for _, v := range filter {
  84. if v == field {
  85. return false
  86. }
  87. if strings.Contains(field, ":") {
  88. image := strings.Split(field, ":")
  89. if image[0] == v {
  90. return false
  91. }
  92. }
  93. }
  94. return true
  95. }
  96. d := s.daemon
  97. es := d.EventsService
  98. w.Header().Set("Content-Type", "application/json")
  99. outStream := ioutils.NewWriteFlusher(w)
  100. // Write an empty chunk of data.
  101. // This is to ensure that the HTTP status code is sent immediately,
  102. // so that it will not block the receiver.
  103. outStream.Write(nil)
  104. enc := json.NewEncoder(outStream)
  105. getContainerID := func(cn string) string {
  106. c, err := d.Get(ctx, cn)
  107. if err != nil {
  108. return ""
  109. }
  110. return c.ID
  111. }
  112. sendEvent := func(ev *jsonmessage.JSONMessage) error {
  113. //incoming container filter can be name,id or partial id, convert and replace as a full container id
  114. for i, cn := range ef["container"] {
  115. ef["container"][i] = getContainerID(cn)
  116. }
  117. if isFiltered(ev.Status, ef["event"]) || (isFiltered(ev.ID, ef["image"]) &&
  118. isFiltered(ev.From, ef["image"])) || isFiltered(ev.ID, ef["container"]) {
  119. return nil
  120. }
  121. return enc.Encode(ev)
  122. }
  123. current, l := es.Subscribe()
  124. if since == -1 {
  125. current = nil
  126. }
  127. defer es.Evict(l)
  128. for _, ev := range current {
  129. if ev.Time < since {
  130. continue
  131. }
  132. if err := sendEvent(ev); err != nil {
  133. return err
  134. }
  135. }
  136. var closeNotify <-chan bool
  137. if closeNotifier, ok := w.(http.CloseNotifier); ok {
  138. closeNotify = closeNotifier.CloseNotify()
  139. }
  140. for {
  141. select {
  142. case ev := <-l:
  143. jev, ok := ev.(*jsonmessage.JSONMessage)
  144. if !ok {
  145. continue
  146. }
  147. if err := sendEvent(jev); err != nil {
  148. return err
  149. }
  150. case <-timer.C:
  151. return nil
  152. case <-closeNotify:
  153. logrus.Debug("Client disconnected, stop sending events")
  154. return nil
  155. }
  156. }
  157. }