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