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, &registry.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  }