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