github.com/mheon/docker@v0.11.2-0.20150922122814-44f47903a831/api/server/daemon.go (about)

     1  package server
     2  
     3  import (
     4  	"encoding/json"
     5  	"net/http"
     6  	"runtime"
     7  	"strconv"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/Sirupsen/logrus"
    12  	"github.com/docker/docker/api"
    13  	"github.com/docker/docker/api/types"
    14  	"github.com/docker/docker/autogen/dockerversion"
    15  	"github.com/docker/docker/context"
    16  	"github.com/docker/docker/pkg/ioutils"
    17  	"github.com/docker/docker/pkg/jsonmessage"
    18  	"github.com/docker/docker/pkg/parsers/filters"
    19  	"github.com/docker/docker/pkg/parsers/kernel"
    20  	"github.com/docker/docker/utils"
    21  )
    22  
    23  func (s *Server) getVersion(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
    24  	v := &types.Version{
    25  		Version:    dockerversion.VERSION,
    26  		APIVersion: api.Version,
    27  		GitCommit:  dockerversion.GITCOMMIT,
    28  		GoVersion:  runtime.Version(),
    29  		Os:         runtime.GOOS,
    30  		Arch:       runtime.GOARCH,
    31  		BuildTime:  dockerversion.BUILDTIME,
    32  	}
    33  
    34  	version := ctx.Version()
    35  
    36  	if version.GreaterThanOrEqualTo("1.19") {
    37  		v.Experimental = utils.ExperimentalBuild()
    38  	}
    39  
    40  	if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
    41  		v.KernelVersion = kernelVersion.String()
    42  	}
    43  
    44  	return writeJSON(w, http.StatusOK, v)
    45  }
    46  
    47  func (s *Server) getInfo(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
    48  	info, err := s.daemon.SystemInfo()
    49  	if err != nil {
    50  		return err
    51  	}
    52  
    53  	return writeJSON(w, http.StatusOK, info)
    54  }
    55  
    56  func (s *Server) getEvents(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
    57  	if err := parseForm(r); err != nil {
    58  		return err
    59  	}
    60  	var since int64 = -1
    61  	if r.Form.Get("since") != "" {
    62  		s, err := strconv.ParseInt(r.Form.Get("since"), 10, 64)
    63  		if err != nil {
    64  			return err
    65  		}
    66  		since = s
    67  	}
    68  
    69  	var until int64 = -1
    70  	if r.Form.Get("until") != "" {
    71  		u, err := strconv.ParseInt(r.Form.Get("until"), 10, 64)
    72  		if err != nil {
    73  			return err
    74  		}
    75  		until = u
    76  	}
    77  
    78  	timer := time.NewTimer(0)
    79  	timer.Stop()
    80  	if until > 0 {
    81  		dur := time.Unix(until, 0).Sub(time.Now())
    82  		timer = time.NewTimer(dur)
    83  	}
    84  
    85  	ef, err := filters.FromParam(r.Form.Get("filters"))
    86  	if err != nil {
    87  		return err
    88  	}
    89  
    90  	isFiltered := func(field string, filter []string) bool {
    91  		if len(field) == 0 {
    92  			return false
    93  		}
    94  		if len(filter) == 0 {
    95  			return false
    96  		}
    97  		for _, v := range filter {
    98  			if v == field {
    99  				return false
   100  			}
   101  			if strings.Contains(field, ":") {
   102  				image := strings.Split(field, ":")
   103  				if image[0] == v {
   104  					return false
   105  				}
   106  			}
   107  		}
   108  		return true
   109  	}
   110  
   111  	d := s.daemon
   112  	es := d.EventsService
   113  	w.Header().Set("Content-Type", "application/json")
   114  
   115  	outStream := ioutils.NewWriteFlusher(w)
   116  	// Write an empty chunk of data.
   117  	// This is to ensure that the HTTP status code is sent immediately,
   118  	// so that it will not block the receiver.
   119  	outStream.Write(nil)
   120  	enc := json.NewEncoder(outStream)
   121  
   122  	getContainerID := func(cn string) string {
   123  		c, err := d.Get(cn)
   124  		if err != nil {
   125  			return ""
   126  		}
   127  		return c.ID
   128  	}
   129  
   130  	sendEvent := func(ev *jsonmessage.JSONMessage) error {
   131  		//incoming container filter can be name,id or partial id, convert and replace as a full container id
   132  		for i, cn := range ef["container"] {
   133  			ef["container"][i] = getContainerID(cn)
   134  		}
   135  
   136  		if isFiltered(ev.Status, ef["event"]) || (isFiltered(ev.ID, ef["image"]) &&
   137  			isFiltered(ev.From, ef["image"])) || isFiltered(ev.ID, ef["container"]) {
   138  			return nil
   139  		}
   140  
   141  		return enc.Encode(ev)
   142  	}
   143  
   144  	current, l := es.Subscribe()
   145  	if since == -1 {
   146  		current = nil
   147  	}
   148  	defer es.Evict(l)
   149  	for _, ev := range current {
   150  		if ev.Time < since {
   151  			continue
   152  		}
   153  		if err := sendEvent(ev); err != nil {
   154  			return err
   155  		}
   156  	}
   157  
   158  	var closeNotify <-chan bool
   159  	if closeNotifier, ok := w.(http.CloseNotifier); ok {
   160  		closeNotify = closeNotifier.CloseNotify()
   161  	}
   162  
   163  	for {
   164  		select {
   165  		case ev := <-l:
   166  			jev, ok := ev.(*jsonmessage.JSONMessage)
   167  			if !ok {
   168  				continue
   169  			}
   170  			if err := sendEvent(jev); err != nil {
   171  				return err
   172  			}
   173  		case <-timer.C:
   174  			return nil
   175  		case <-closeNotify:
   176  			logrus.Debug("Client disconnected, stop sending events")
   177  			return nil
   178  		}
   179  	}
   180  }