github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/integration/plugin/logging/cmd/discard/driver.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/json"
     5  	"io"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"os"
     9  	"sync"
    10  	"syscall"
    11  )
    12  
    13  type startLoggingRequest struct {
    14  	File string
    15  }
    16  
    17  type capabilitiesResponse struct {
    18  	Cap struct {
    19  		ReadLogs bool
    20  	}
    21  }
    22  
    23  type driver struct {
    24  	mu   sync.Mutex
    25  	logs map[string]io.Closer
    26  }
    27  
    28  type stopLoggingRequest struct {
    29  	File string
    30  }
    31  
    32  func handle(mux *http.ServeMux) {
    33  	d := &driver{logs: make(map[string]io.Closer)}
    34  	mux.HandleFunc("/LogDriver.StartLogging", func(w http.ResponseWriter, r *http.Request) {
    35  		var req startLoggingRequest
    36  		if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
    37  			http.Error(w, err.Error(), http.StatusBadRequest)
    38  			return
    39  		}
    40  
    41  		f, err := os.OpenFile(req.File, syscall.O_RDONLY, 0700)
    42  		if err != nil {
    43  			respond(err, w)
    44  		}
    45  
    46  		d.mu.Lock()
    47  		d.logs[req.File] = f
    48  		d.mu.Unlock()
    49  
    50  		go io.Copy(ioutil.Discard, f)
    51  		respond(err, w)
    52  	})
    53  
    54  	mux.HandleFunc("/LogDriver.StopLogging", func(w http.ResponseWriter, r *http.Request) {
    55  		var req stopLoggingRequest
    56  		if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
    57  			http.Error(w, err.Error(), http.StatusBadRequest)
    58  			return
    59  		}
    60  
    61  		d.mu.Lock()
    62  		if f := d.logs[req.File]; f != nil {
    63  			f.Close()
    64  		}
    65  		d.mu.Unlock()
    66  		respond(nil, w)
    67  	})
    68  
    69  	mux.HandleFunc("/LogDriver.Capabilities", func(w http.ResponseWriter, r *http.Request) {
    70  		json.NewEncoder(w).Encode(&capabilitiesResponse{
    71  			Cap: struct{ ReadLogs bool }{ReadLogs: false},
    72  		})
    73  	})
    74  }
    75  
    76  type response struct {
    77  	Err string
    78  }
    79  
    80  func respond(err error, w io.Writer) {
    81  	var res response
    82  	if err != nil {
    83  		res.Err = err.Error()
    84  	}
    85  	json.NewEncoder(w).Encode(&res)
    86  }