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