github.com/kim0/docker@v0.6.2-0.20161130212042-4addda3f07e7/api/server/router/system/system_routes.go (about) 1 package system 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "time" 8 9 "github.com/Sirupsen/logrus" 10 "github.com/docker/docker/api" 11 "github.com/docker/docker/api/errors" 12 "github.com/docker/docker/api/server/httputils" 13 "github.com/docker/docker/api/types" 14 "github.com/docker/docker/api/types/events" 15 "github.com/docker/docker/api/types/filters" 16 timetypes "github.com/docker/docker/api/types/time" 17 "github.com/docker/docker/api/types/versions" 18 "github.com/docker/docker/pkg/ioutils" 19 "golang.org/x/net/context" 20 ) 21 22 func optionsHandler(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 23 w.WriteHeader(http.StatusOK) 24 return nil 25 } 26 27 func pingHandler(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 28 _, err := w.Write([]byte{'O', 'K'}) 29 return err 30 } 31 32 func (s *systemRouter) getInfo(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 33 info, err := s.backend.SystemInfo() 34 if err != nil { 35 return err 36 } 37 if s.clusterProvider != nil { 38 info.Swarm = s.clusterProvider.Info() 39 } 40 41 if versions.LessThan(httputils.VersionFromContext(ctx), "1.25") { 42 // TODO: handle this conversion in engine-api 43 type oldInfo struct { 44 *types.Info 45 ExecutionDriver string 46 } 47 return httputils.WriteJSON(w, http.StatusOK, &oldInfo{Info: info, ExecutionDriver: "<not supported>"}) 48 } 49 return httputils.WriteJSON(w, http.StatusOK, info) 50 } 51 52 func (s *systemRouter) getVersion(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 53 info := s.backend.SystemVersion() 54 info.APIVersion = api.DefaultVersion 55 56 return httputils.WriteJSON(w, http.StatusOK, info) 57 } 58 59 func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 60 du, err := s.backend.SystemDiskUsage() 61 if err != nil { 62 return err 63 } 64 65 return httputils.WriteJSON(w, http.StatusOK, du) 66 } 67 68 func (s *systemRouter) getEvents(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 69 if err := httputils.ParseForm(r); err != nil { 70 return err 71 } 72 73 since, err := eventTime(r.Form.Get("since")) 74 if err != nil { 75 return err 76 } 77 until, err := eventTime(r.Form.Get("until")) 78 if err != nil { 79 return err 80 } 81 82 var ( 83 timeout <-chan time.Time 84 onlyPastEvents bool 85 ) 86 if !until.IsZero() { 87 if until.Before(since) { 88 return errors.NewBadRequestError(fmt.Errorf("`since` time (%s) cannot be after `until` time (%s)", r.Form.Get("since"), r.Form.Get("until"))) 89 } 90 91 now := time.Now() 92 93 onlyPastEvents = until.Before(now) 94 95 if !onlyPastEvents { 96 dur := until.Sub(now) 97 timeout = time.NewTimer(dur).C 98 } 99 } 100 101 ef, err := filters.FromParam(r.Form.Get("filters")) 102 if err != nil { 103 return err 104 } 105 106 w.Header().Set("Content-Type", "application/json") 107 output := ioutils.NewWriteFlusher(w) 108 defer output.Close() 109 output.Flush() 110 111 enc := json.NewEncoder(output) 112 113 buffered, l := s.backend.SubscribeToEvents(since, until, ef) 114 defer s.backend.UnsubscribeFromEvents(l) 115 116 for _, ev := range buffered { 117 if err := enc.Encode(ev); err != nil { 118 return err 119 } 120 } 121 122 if onlyPastEvents { 123 return nil 124 } 125 126 for { 127 select { 128 case ev := <-l: 129 jev, ok := ev.(events.Message) 130 if !ok { 131 logrus.Warnf("unexpected event message: %q", ev) 132 continue 133 } 134 if err := enc.Encode(jev); err != nil { 135 return err 136 } 137 case <-timeout: 138 return nil 139 case <-ctx.Done(): 140 logrus.Debug("Client context cancelled, stop sending events") 141 return nil 142 } 143 } 144 } 145 146 func (s *systemRouter) postAuth(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 147 var config *types.AuthConfig 148 err := json.NewDecoder(r.Body).Decode(&config) 149 r.Body.Close() 150 if err != nil { 151 return err 152 } 153 status, token, err := s.backend.AuthenticateToRegistry(ctx, config) 154 if err != nil { 155 return err 156 } 157 return httputils.WriteJSON(w, http.StatusOK, &types.AuthResponse{ 158 Status: status, 159 IdentityToken: token, 160 }) 161 } 162 163 func eventTime(formTime string) (time.Time, error) { 164 t, tNano, err := timetypes.ParseTimestamps(formTime, -1) 165 if err != nil { 166 return time.Time{}, err 167 } 168 if t == -1 { 169 return time.Time{}, nil 170 } 171 return time.Unix(t, tNano), nil 172 }