github.com/rsampaio/docker@v0.7.2-0.20150827203920-fdc73cc3fc31/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/pkg/ioutils"
    16  	"github.com/docker/docker/pkg/jsonmessage"
    17  	"github.com/docker/docker/pkg/parsers/filters"
    18  	"github.com/docker/docker/pkg/parsers/kernel"
    19  	"github.com/docker/docker/pkg/version"
    20  	"github.com/docker/docker/utils"
    21  )
    22  
    23  func (s *Server) getVersion(version version.Version, 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  	if version.GreaterThanOrEqualTo("1.19") {
    35  		v.Experimental = utils.ExperimentalBuild()
    36  	}
    37  
    38  	if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
    39  		v.KernelVersion = kernelVersion.String()
    40  	}
    41  
    42  	return writeJSON(w, http.StatusOK, v)
    43  }
    44  
    45  func (s *Server) getInfo(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
    46  	info, err := s.daemon.SystemInfo()
    47  	if err != nil {
    48  		return err
    49  	}
    50  
    51  	return writeJSON(w, http.StatusOK, info)
    52  }
    53  
    54  func (s *Server) getEvents(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
    55  	if err := parseForm(r); err != nil {
    56  		return err
    57  	}
    58  	var since int64 = -1
    59  	if r.Form.Get("since") != "" {
    60  		s, err := strconv.ParseInt(r.Form.Get("since"), 10, 64)
    61  		if err != nil {
    62  			return err
    63  		}
    64  		since = s
    65  	}
    66  
    67  	var until int64 = -1
    68  	if r.Form.Get("until") != "" {
    69  		u, err := strconv.ParseInt(r.Form.Get("until"), 10, 64)
    70  		if err != nil {
    71  			return err
    72  		}
    73  		until = u
    74  	}
    75  
    76  	timer := time.NewTimer(0)
    77  	timer.Stop()
    78  	if until > 0 {
    79  		dur := time.Unix(until, 0).Sub(time.Now())
    80  		timer = time.NewTimer(dur)
    81  	}
    82  
    83  	ef, err := filters.FromParam(r.Form.Get("filters"))
    84  	if err != nil {
    85  		return err
    86  	}
    87  
    88  	isFiltered := func(field string, filter []string) bool {
    89  		if len(field) == 0 {
    90  			return false
    91  		}
    92  		if len(filter) == 0 {
    93  			return false
    94  		}
    95  		for _, v := range filter {
    96  			if v == field {
    97  				return false
    98  			}
    99  			if strings.Contains(field, ":") {
   100  				image := strings.Split(field, ":")
   101  				if image[0] == v {
   102  					return false
   103  				}
   104  			}
   105  		}
   106  		return true
   107  	}
   108  
   109  	d := s.daemon
   110  	es := d.EventsService
   111  	w.Header().Set("Content-Type", "application/json")
   112  	outStream := ioutils.NewWriteFlusher(w)
   113  	outStream.Write(nil) // make sure response is sent immediately
   114  	enc := json.NewEncoder(outStream)
   115  
   116  	getContainerID := func(cn string) string {
   117  		c, err := d.Get(cn)
   118  		if err != nil {
   119  			return ""
   120  		}
   121  		return c.ID
   122  	}
   123  
   124  	sendEvent := func(ev *jsonmessage.JSONMessage) error {
   125  		//incoming container filter can be name,id or partial id, convert and replace as a full container id
   126  		for i, cn := range ef["container"] {
   127  			ef["container"][i] = getContainerID(cn)
   128  		}
   129  
   130  		if isFiltered(ev.Status, ef["event"]) || (isFiltered(ev.ID, ef["image"]) &&
   131  			isFiltered(ev.From, ef["image"])) || isFiltered(ev.ID, ef["container"]) {
   132  			return nil
   133  		}
   134  
   135  		return enc.Encode(ev)
   136  	}
   137  
   138  	current, l := es.Subscribe()
   139  	if since == -1 {
   140  		current = nil
   141  	}
   142  	defer es.Evict(l)
   143  	for _, ev := range current {
   144  		if ev.Time < since {
   145  			continue
   146  		}
   147  		if err := sendEvent(ev); err != nil {
   148  			return err
   149  		}
   150  	}
   151  
   152  	var closeNotify <-chan bool
   153  	if closeNotifier, ok := w.(http.CloseNotifier); ok {
   154  		closeNotify = closeNotifier.CloseNotify()
   155  	}
   156  
   157  	for {
   158  		select {
   159  		case ev := <-l:
   160  			jev, ok := ev.(*jsonmessage.JSONMessage)
   161  			if !ok {
   162  				continue
   163  			}
   164  			if err := sendEvent(jev); err != nil {
   165  				return err
   166  			}
   167  		case <-timer.C:
   168  			return nil
   169  		case <-closeNotify:
   170  			logrus.Debug("Client disconnected, stop sending events")
   171  			return nil
   172  		}
   173  	}
   174  }