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