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  }