github.com/rsampaio/docker@v0.7.2-0.20150827203920-fdc73cc3fc31/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/pkg/ioutils" 16 "github.com/docker/docker/pkg/jsonmessage" 17 "github.com/docker/docker/pkg/parsers/filters" 18 "github.com/docker/docker/pkg/parsers/kernel" 19 "github.com/docker/docker/pkg/version" 20 "github.com/docker/docker/utils" 21 ) 22 23 func (s *Server) getVersion(version version.Version, 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 if version.GreaterThanOrEqualTo("1.19") { 35 v.Experimental = utils.ExperimentalBuild() 36 } 37 38 if kernelVersion, err := kernel.GetKernelVersion(); err == nil { 39 v.KernelVersion = kernelVersion.String() 40 } 41 42 return writeJSON(w, http.StatusOK, v) 43 } 44 45 func (s *Server) getInfo(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 46 info, err := s.daemon.SystemInfo() 47 if err != nil { 48 return err 49 } 50 51 return writeJSON(w, http.StatusOK, info) 52 } 53 54 func (s *Server) getEvents(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 55 if err := parseForm(r); err != nil { 56 return err 57 } 58 var since int64 = -1 59 if r.Form.Get("since") != "" { 60 s, err := strconv.ParseInt(r.Form.Get("since"), 10, 64) 61 if err != nil { 62 return err 63 } 64 since = s 65 } 66 67 var until int64 = -1 68 if r.Form.Get("until") != "" { 69 u, err := strconv.ParseInt(r.Form.Get("until"), 10, 64) 70 if err != nil { 71 return err 72 } 73 until = u 74 } 75 76 timer := time.NewTimer(0) 77 timer.Stop() 78 if until > 0 { 79 dur := time.Unix(until, 0).Sub(time.Now()) 80 timer = time.NewTimer(dur) 81 } 82 83 ef, err := filters.FromParam(r.Form.Get("filters")) 84 if err != nil { 85 return err 86 } 87 88 isFiltered := func(field string, filter []string) bool { 89 if len(field) == 0 { 90 return false 91 } 92 if len(filter) == 0 { 93 return false 94 } 95 for _, v := range filter { 96 if v == field { 97 return false 98 } 99 if strings.Contains(field, ":") { 100 image := strings.Split(field, ":") 101 if image[0] == v { 102 return false 103 } 104 } 105 } 106 return true 107 } 108 109 d := s.daemon 110 es := d.EventsService 111 w.Header().Set("Content-Type", "application/json") 112 outStream := ioutils.NewWriteFlusher(w) 113 outStream.Write(nil) // make sure response is sent immediately 114 enc := json.NewEncoder(outStream) 115 116 getContainerID := func(cn string) string { 117 c, err := d.Get(cn) 118 if err != nil { 119 return "" 120 } 121 return c.ID 122 } 123 124 sendEvent := func(ev *jsonmessage.JSONMessage) error { 125 //incoming container filter can be name,id or partial id, convert and replace as a full container id 126 for i, cn := range ef["container"] { 127 ef["container"][i] = getContainerID(cn) 128 } 129 130 if isFiltered(ev.Status, ef["event"]) || (isFiltered(ev.ID, ef["image"]) && 131 isFiltered(ev.From, ef["image"])) || isFiltered(ev.ID, ef["container"]) { 132 return nil 133 } 134 135 return enc.Encode(ev) 136 } 137 138 current, l := es.Subscribe() 139 if since == -1 { 140 current = nil 141 } 142 defer es.Evict(l) 143 for _, ev := range current { 144 if ev.Time < since { 145 continue 146 } 147 if err := sendEvent(ev); err != nil { 148 return err 149 } 150 } 151 152 var closeNotify <-chan bool 153 if closeNotifier, ok := w.(http.CloseNotifier); ok { 154 closeNotify = closeNotifier.CloseNotify() 155 } 156 157 for { 158 select { 159 case ev := <-l: 160 jev, ok := ev.(*jsonmessage.JSONMessage) 161 if !ok { 162 continue 163 } 164 if err := sendEvent(jev); err != nil { 165 return err 166 } 167 case <-timer.C: 168 return nil 169 case <-closeNotify: 170 logrus.Debug("Client disconnected, stop sending events") 171 return nil 172 } 173 } 174 }