diff --git a/README.md b/README.md index d00f26c..2e27f96 100644 --- a/README.md +++ b/README.md @@ -11,3 +11,18 @@ A collection of helper packages to extend Docker Engine in Go Graph (experimental) | [Link](https://github.com/docker/docker/blob/master/experimental/plugins_graphdriver.md) | Extend image and container fs storage See the [understand Docker plugins documentation section](https://docs.docker.com/engine/extend/plugins/). + +# Serving multiple drivers on a single socket +```go +import ( + "github.com/docker/go-plugins-helpers/sdk" + "github.com/docker/go-plugins-helpers/ipam" + "github.com/docker/go-plugins-helpers/network" +) +dIPAM := MyIPAMDriver{} +dNetwork := MyNetworkDriver{} +h := sdk.NewHandler() +ipam.RegisterDriver(dIPAM, h) +network.RegisterDriver(dNetwork,h) +h.ServeUnix("/var/run/docker/plugins/myplugin.sock", 1001) +``` diff --git a/authorization/api.go b/authorization/api.go index 0c63f42..d8fc133 100644 --- a/authorization/api.go +++ b/authorization/api.go @@ -9,9 +9,8 @@ import ( ) const ( - manifest = `{"Implements": ["` + authorization.AuthZApiImplements + `"]}` - reqPath = "/" + authorization.AuthZApiRequest - resPath = "/" + authorization.AuthZApiResponse + reqPath = "/" + authorization.AuthZApiRequest + resPath = "/" + authorization.AuthZApiResponse ) // Request is the structure that docker's requests are deserialized to. @@ -26,32 +25,33 @@ type Plugin interface { AuthZRes(Request) Response } -// Handler forwards requests and responses between the docker daemon and the plugin. -type Handler struct { - plugin Plugin - sdk.Handler -} - // NewHandler initializes the request handler with a plugin implementation. -func NewHandler(plugin Plugin) *Handler { - h := &Handler{plugin, sdk.NewHandler(manifest)} - h.initMux() +func NewHandler(plugin Plugin) *sdk.Handler { + h := sdk.NewHandler() + RegisterDriver(plugin, h) return h } -func (h *Handler) initMux() { - h.handle(reqPath, func(req Request) Response { - return h.plugin.AuthZReq(req) +// RegisterDriver registers the plugin to the SDK handler. +func RegisterDriver(plugin Plugin, h *sdk.Handler) { + h.RegisterDriver(authorization.AuthZApiImplements, func(h *sdk.Handler) { + initMux(plugin, h) + }) +} + +func initMux(plugin Plugin, h *sdk.Handler) { + handle(h, reqPath, func(req Request) Response { + return plugin.AuthZReq(req) }) - h.handle(resPath, func(req Request) Response { - return h.plugin.AuthZRes(req) + handle(h, resPath, func(req Request) Response { + return plugin.AuthZRes(req) }) } type actionHandler func(Request) Response -func (h *Handler) handle(name string, actionCall actionHandler) { +func handle(h *sdk.Handler, name string, actionCall actionHandler) { h.HandleFunc(name, func(w http.ResponseWriter, r *http.Request) { var ( req Request diff --git a/authorization/api_test.go b/authorization/api_test.go index 1f1ac2f..0a25f79 100644 --- a/authorization/api_test.go +++ b/authorization/api_test.go @@ -8,6 +8,7 @@ import ( "strings" "testing" + "github.com/docker/docker/pkg/authorization" "github.com/docker/go-plugins-helpers/sdk" ) @@ -46,8 +47,8 @@ func TestActivate(t *testing.T) { t.Fatal(err) } - if string(body) != manifest+"\n" { - t.Fatalf("Expected %s, got %s\n", manifest+"\n", string(body)) + if !strings.Contains(string(body), authorization.AuthZApiImplements) { + t.Fatalf("Expected driver to implement %s, got %s\n", authorization.AuthZApiImplements, string(body)) } } diff --git a/graphdriver/api.go b/graphdriver/api.go index 673c3ca..699fc36 100644 --- a/graphdriver/api.go +++ b/graphdriver/api.go @@ -16,7 +16,7 @@ const ( // DefaultDockerRootDirectory is the default directory where graph drivers will be created. DefaultDockerRootDirectory = "/var/lib/docker/graph" - manifest = `{"Implements": ["GraphDriver"]}` + driverName = "GraphDriver" initPath = "/GraphDriver.Init" createPath = "/GraphDriver.Create" createRWPath = "/GraphDriver.CreateReadWrite" @@ -238,27 +238,28 @@ type Driver interface { DiffSize(id, parent string) (int64, error) } -// Handler forwards requests and responses between the docker daemon and the plugin. -type Handler struct { - driver Driver - sdk.Handler -} - // NewHandler initializes the request handler with a driver implementation. -func NewHandler(driver Driver) *Handler { - h := &Handler{driver, sdk.NewHandler(manifest)} - h.initMux() +func NewHandler(driver Driver) *sdk.Handler { + h := sdk.NewHandler() + RegisterDriver(driver, h) return h } -func (h *Handler) initMux() { +// RegisterDriver registers the plugin to the SDK handler. +func RegisterDriver(driver Driver, h *sdk.Handler) { + h.RegisterDriver(driverName, func(h *sdk.Handler) { + initMux(driver, h) + }) +} + +func initMux(driver Driver, h *sdk.Handler) { h.HandleFunc(initPath, func(w http.ResponseWriter, r *http.Request) { req := InitRequest{} err := sdk.DecodeRequest(w, r, &req) if err != nil { return } - err = h.driver.Init(req.Home, req.Options, req.UIDMaps, req.GIDMaps) + err = driver.Init(req.Home, req.Options, req.UIDMaps, req.GIDMaps) msg := "" if err != nil { msg = err.Error() @@ -271,7 +272,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.driver.Create(req.ID, req.Parent, req.MountLabel, req.StorageOpt) + err = driver.Create(req.ID, req.Parent, req.MountLabel, req.StorageOpt) msg := "" if err != nil { msg = err.Error() @@ -284,7 +285,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.driver.CreateReadWrite(req.ID, req.Parent, req.MountLabel, req.StorageOpt) + err = driver.CreateReadWrite(req.ID, req.Parent, req.MountLabel, req.StorageOpt) msg := "" if err != nil { msg = err.Error() @@ -297,7 +298,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.driver.Remove(req.ID) + err = driver.Remove(req.ID) msg := "" if err != nil { msg = err.Error() @@ -311,7 +312,7 @@ func (h *Handler) initMux() { if err != nil { return } - dir, err := h.driver.Get(req.ID, req.MountLabel) + dir, err := driver.Get(req.ID, req.MountLabel) msg := "" if err != nil { msg = err.Error() @@ -324,7 +325,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.driver.Put(req.ID) + err = driver.Put(req.ID) msg := "" if err != nil { msg = err.Error() @@ -337,11 +338,11 @@ func (h *Handler) initMux() { if err != nil { return } - exists := h.driver.Exists(req.ID) + exists := driver.Exists(req.ID) sdk.EncodeResponse(w, &ExistsResponse{Exists: exists}, "") }) h.HandleFunc(statusPath, func(w http.ResponseWriter, r *http.Request) { - status := h.driver.Status() + status := driver.Status() sdk.EncodeResponse(w, &StatusResponse{Status: status}, "") }) h.HandleFunc(getMetadataPath, func(w http.ResponseWriter, r *http.Request) { @@ -350,7 +351,7 @@ func (h *Handler) initMux() { if err != nil { return } - metadata, err := h.driver.GetMetadata(req.ID) + metadata, err := driver.GetMetadata(req.ID) msg := "" if err != nil { msg = err.Error() @@ -358,7 +359,7 @@ func (h *Handler) initMux() { sdk.EncodeResponse(w, &GetMetadataResponse{Err: msg, Metadata: metadata}, msg) }) h.HandleFunc(cleanupPath, func(w http.ResponseWriter, r *http.Request) { - err := h.driver.Cleanup() + err := driver.Cleanup() msg := "" if err != nil { msg = err.Error() @@ -371,7 +372,7 @@ func (h *Handler) initMux() { if err != nil { return } - stream := h.driver.Diff(req.ID, req.Parent) + stream := driver.Diff(req.ID, req.Parent) sdk.StreamResponse(w, stream) }) h.HandleFunc(changesPath, func(w http.ResponseWriter, r *http.Request) { @@ -380,7 +381,7 @@ func (h *Handler) initMux() { if err != nil { return } - changes, err := h.driver.Changes(req.ID, req.Parent) + changes, err := driver.Changes(req.ID, req.Parent) msg := "" if err != nil { msg = err.Error() @@ -391,7 +392,7 @@ func (h *Handler) initMux() { params := r.URL.Query() id := params.Get("id") parent := params.Get("parent") - size, err := h.driver.ApplyDiff(id, parent, r.Body) + size, err := driver.ApplyDiff(id, parent, r.Body) msg := "" if err != nil { msg = err.Error() @@ -404,7 +405,7 @@ func (h *Handler) initMux() { if err != nil { return } - size, err := h.driver.DiffSize(req.ID, req.Parent) + size, err := driver.DiffSize(req.ID, req.Parent) msg := "" if err != nil { msg = err.Error() diff --git a/graphdriver/shim/shim.go b/graphdriver/shim/shim.go index db81bf0..a77a6eb 100644 --- a/graphdriver/shim/shim.go +++ b/graphdriver/shim/shim.go @@ -9,6 +9,7 @@ import ( "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/idtools" graphPlugin "github.com/docker/go-plugins-helpers/graphdriver" + "github.com/docker/go-plugins-helpers/sdk" ) type shimDriver struct { @@ -21,7 +22,7 @@ type shimDriver struct { // built-in to Docker Engine and it would create a plugin from it that maps // plugin API calls directly to any volume driver that satifies the // graphdriver.Driver interface from Docker Engine. -func NewHandlerFromGraphDriver(init graphDriver.InitFunc) *graphPlugin.Handler { +func NewHandlerFromGraphDriver(init graphDriver.InitFunc) *sdk.Handler { return graphPlugin.NewHandler(&shimDriver{driver: nil, init: init}) } diff --git a/ipam/api.go b/ipam/api.go index 284bc0d..027cf42 100644 --- a/ipam/api.go +++ b/ipam/api.go @@ -7,7 +7,7 @@ import ( ) const ( - manifest = `{"Implements": ["IpamDriver"]}` + driverName = "IpamDriver" capabilitiesPath = "/IpamDriver.GetCapabilities" addressSpacesPath = "/IpamDriver.GetDefaultAddressSpaces" @@ -88,22 +88,23 @@ func NewErrorResponse(msg string) *ErrorResponse { return &ErrorResponse{Err: msg} } -// Handler forwards requests and responses between the docker daemon and the plugin. -type Handler struct { - ipam Ipam - sdk.Handler -} - // NewHandler initializes the request handler with a driver implementation. -func NewHandler(ipam Ipam) *Handler { - h := &Handler{ipam, sdk.NewHandler(manifest)} - h.initMux() +func NewHandler(ipam Ipam) *sdk.Handler { + h := sdk.NewHandler() + RegisterDriver(ipam, h) return h } -func (h *Handler) initMux() { +// RegisterDriver registers the plugin to the SDK handler. +func RegisterDriver(ipam Ipam, h *sdk.Handler) { + h.RegisterDriver(driverName, func(h *sdk.Handler) { + initMux(ipam, h) + }) +} + +func initMux(ipam Ipam, h *sdk.Handler) { h.HandleFunc(capabilitiesPath, func(w http.ResponseWriter, r *http.Request) { - res, err := h.ipam.GetCapabilities() + res, err := ipam.GetCapabilities() if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -112,7 +113,7 @@ func (h *Handler) initMux() { sdk.EncodeResponse(w, res, "") }) h.HandleFunc(addressSpacesPath, func(w http.ResponseWriter, r *http.Request) { - res, err := h.ipam.GetDefaultAddressSpaces() + res, err := ipam.GetDefaultAddressSpaces() if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -126,7 +127,7 @@ func (h *Handler) initMux() { if err != nil { return } - res, err := h.ipam.RequestPool(req) + res, err := ipam.RequestPool(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -140,7 +141,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.ipam.ReleasePool(req) + err = ipam.ReleasePool(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -154,7 +155,7 @@ func (h *Handler) initMux() { if err != nil { return } - res, err := h.ipam.RequestAddress(req) + res, err := ipam.RequestAddress(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -168,7 +169,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.ipam.ReleaseAddress(req) + err = ipam.ReleaseAddress(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) diff --git a/network/api.go b/network/api.go index 111b376..c415b7c 100644 --- a/network/api.go +++ b/network/api.go @@ -8,7 +8,7 @@ import ( ) const ( - manifest = `{"Implements": ["NetworkDriver"]}` + driverName = "NetworkDriver" // LocalScope is the correct scope response for a local scope driver LocalScope = `local` // GlobalScope is the correct scope response for a global scope driver @@ -205,22 +205,23 @@ func NewErrorResponse(msg string) *ErrorResponse { return &ErrorResponse{Err: msg} } -// Handler forwards requests and responses between the docker daemon and the plugin. -type Handler struct { - driver Driver - sdk.Handler -} - // NewHandler initializes the request handler with a driver implementation. -func NewHandler(driver Driver) *Handler { - h := &Handler{driver, sdk.NewHandler(manifest)} - h.initMux() +func NewHandler(driver Driver) *sdk.Handler { + h := sdk.NewHandler() + RegisterDriver(driver, h) return h } -func (h *Handler) initMux() { +// RegisterDriver registers the plugin to the SDK handler. +func RegisterDriver(driver Driver, h *sdk.Handler) { + h.RegisterDriver(driverName, func(h *sdk.Handler) { + initMux(driver, h) + }) +} + +func initMux(driver Driver, h *sdk.Handler) { h.HandleFunc(capabilitiesPath, func(w http.ResponseWriter, r *http.Request) { - res, err := h.driver.GetCapabilities() + res, err := driver.GetCapabilities() if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -240,7 +241,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.driver.CreateNetwork(req) + err = driver.CreateNetwork(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -255,7 +256,7 @@ func (h *Handler) initMux() { if err != nil { return } - res, err := h.driver.AllocateNetwork(req) + res, err := driver.AllocateNetwork(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -269,7 +270,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.driver.DeleteNetwork(req) + err = driver.DeleteNetwork(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -283,7 +284,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.driver.FreeNetwork(req) + err = driver.FreeNetwork(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -297,7 +298,7 @@ func (h *Handler) initMux() { if err != nil { return } - res, err := h.driver.CreateEndpoint(req) + res, err := driver.CreateEndpoint(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -311,7 +312,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.driver.DeleteEndpoint(req) + err = driver.DeleteEndpoint(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -325,7 +326,7 @@ func (h *Handler) initMux() { if err != nil { return } - res, err := h.driver.EndpointInfo(req) + res, err := driver.EndpointInfo(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -338,7 +339,7 @@ func (h *Handler) initMux() { if err != nil { return } - res, err := h.driver.Join(req) + res, err := driver.Join(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -351,7 +352,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.driver.Leave(req) + err = driver.Leave(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -365,7 +366,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.driver.DiscoverNew(req) + err = driver.DiscoverNew(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -379,7 +380,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.driver.DiscoverDelete(req) + err = driver.DiscoverDelete(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -393,7 +394,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.driver.ProgramExternalConnectivity(req) + err = driver.ProgramExternalConnectivity(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) @@ -407,7 +408,7 @@ func (h *Handler) initMux() { if err != nil { return } - err = h.driver.RevokeExternalConnectivity(req) + err = driver.RevokeExternalConnectivity(req) if err != nil { msg := err.Error() sdk.EncodeResponse(w, NewErrorResponse(msg), msg) diff --git a/network/api_test.go b/network/api_test.go index d7befc2..1c36964 100644 --- a/network/api_test.go +++ b/network/api_test.go @@ -115,8 +115,8 @@ func TestActivate(t *testing.T) { defer response.Body.Close() body, err := ioutil.ReadAll(response.Body) - if string(body) != manifest+"\n" { - t.Fatalf("Expected %s, got %s\n", manifest+"\n", string(body)) + if strings.Contains(string(body), driverName) { + t.Fatalf("Expected driver to implement %s, got %s\n", driverName, string(body)) } } diff --git a/sdk/handler.go b/sdk/handler.go index 2dda5fa..3820a6a 100644 --- a/sdk/handler.go +++ b/sdk/handler.go @@ -2,7 +2,7 @@ package sdk import ( "crypto/tls" - "fmt" + "encoding/json" "net" "net/http" "os" @@ -10,26 +10,41 @@ import ( const activatePath = "/Plugin.Activate" +type muxInitilizaer func(*Handler) + +type activationResposne struct { + Implements []string +} + // Handler is the base to create plugin handlers. // It initializes connections and sockets to listen to. type Handler struct { - mux *http.ServeMux + mux *http.ServeMux + drivers map[string]muxInitilizaer } // NewHandler creates a new Handler with an http mux. -func NewHandler(manifest string) Handler { - mux := http.NewServeMux() - - mux.HandleFunc(activatePath, func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", DefaultContentTypeV1_1) - fmt.Fprintln(w, manifest) - }) +func NewHandler() *Handler { + return &Handler{mux: http.NewServeMux(), drivers: make(map[string]muxInitilizaer)} +} - return Handler{mux: mux} +// RegisterDriver registers a Docker driver to the Handler +func (h *Handler) RegisterDriver(driver string, init muxInitilizaer) { + h.drivers[driver] = init } // Serve sets up the handler to serve requests on the passed in listener -func (h Handler) Serve(l net.Listener) error { +func (h *Handler) Serve(l net.Listener) error { + activateResp := activationResposne{} + for d, i := range h.drivers { + activateResp.Implements = append(activateResp.Implements, d) + i(h) + } + h.mux.HandleFunc(activatePath, func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", DefaultContentTypeV1_1) + json.NewEncoder(w).Encode(activateResp) + }) + server := http.Server{ Addr: l.Addr().String(), Handler: h.mux, @@ -39,7 +54,7 @@ func (h Handler) Serve(l net.Listener) error { // ServeTCP makes the handler to listen for request in a given TCP address. // It also writes the spec file on the right directory for docker to read. -func (h Handler) ServeTCP(pluginName, addr string, tlsConfig *tls.Config) error { +func (h *Handler) ServeTCP(pluginName, addr string, tlsConfig *tls.Config) error { l, spec, err := newTCPListener(addr, pluginName, tlsConfig) if err != nil { return err @@ -52,7 +67,7 @@ func (h Handler) ServeTCP(pluginName, addr string, tlsConfig *tls.Config) error // ServeUnix makes the handler to listen for requests in a unix socket. // It also creates the socket file on the right directory for docker to read. -func (h Handler) ServeUnix(addr string, gid int) error { +func (h *Handler) ServeUnix(addr string, gid int) error { l, spec, err := newUnixListener(addr, gid) if err != nil { return err @@ -64,6 +79,6 @@ func (h Handler) ServeUnix(addr string, gid int) error { } // HandleFunc registers a function to handle a request path with. -func (h Handler) HandleFunc(path string, fn func(w http.ResponseWriter, r *http.Request)) { +func (h *Handler) HandleFunc(path string, fn func(w http.ResponseWriter, r *http.Request)) { h.mux.HandleFunc(path, fn) } diff --git a/volume/api.go b/volume/api.go index 283d1b2..3d5642f 100644 --- a/volume/api.go +++ b/volume/api.go @@ -10,7 +10,7 @@ const ( // DefaultDockerRootDirectory is the default directory where volumes will be created. DefaultDockerRootDirectory = "/var/lib/docker-volumes" - manifest = `{"Implements": ["VolumeDriver"]}` + driverName = "VolumeDriver" createPath = "/VolumeDriver.Create" getPath = "/VolumeDriver.Get" listPath = "/VolumeDriver.List" @@ -72,57 +72,58 @@ type Driver interface { Capabilities(Request) Response } -// Handler forwards requests and responses between the docker daemon and the plugin. -type Handler struct { - driver Driver - sdk.Handler -} - type actionHandler func(Request) Response type mountActionHandler func(MountRequest) Response type unmountActionHandler func(UnmountRequest) Response // NewHandler initializes the request handler with a driver implementation. -func NewHandler(driver Driver) *Handler { - h := &Handler{driver, sdk.NewHandler(manifest)} - h.initMux() +func NewHandler(driver Driver) *sdk.Handler { + h := sdk.NewHandler() + RegisterDriver(driver, h) return h } -func (h *Handler) initMux() { - h.handle(createPath, func(req Request) Response { - return h.driver.Create(req) +// RegisterDriver registers the plugin to the SDK handler. +func RegisterDriver(driver Driver, h *sdk.Handler) { + h.RegisterDriver(driverName, func(h *sdk.Handler) { + initMux(driver, h) + }) +} + +func initMux(driver Driver, h *sdk.Handler) { + handle(h, createPath, func(req Request) Response { + return driver.Create(req) }) - h.handle(getPath, func(req Request) Response { - return h.driver.Get(req) + handle(h, getPath, func(req Request) Response { + return driver.Get(req) }) - h.handle(listPath, func(req Request) Response { - return h.driver.List(req) + handle(h, listPath, func(req Request) Response { + return driver.List(req) }) - h.handle(removePath, func(req Request) Response { - return h.driver.Remove(req) + handle(h, removePath, func(req Request) Response { + return driver.Remove(req) }) - h.handle(hostVirtualPath, func(req Request) Response { - return h.driver.Path(req) + handle(h, hostVirtualPath, func(req Request) Response { + return driver.Path(req) }) - h.handleMount(mountPath, func(req MountRequest) Response { - return h.driver.Mount(req) + handleMount(h, mountPath, func(req MountRequest) Response { + return driver.Mount(req) }) - h.handleUnmount(unmountPath, func(req UnmountRequest) Response { - return h.driver.Unmount(req) + handleUnmount(h, unmountPath, func(req UnmountRequest) Response { + return driver.Unmount(req) }) - h.handle(capabilitiesPath, func(req Request) Response { - return h.driver.Capabilities(req) + handle(h, capabilitiesPath, func(req Request) Response { + return driver.Capabilities(req) }) } -func (h *Handler) handle(name string, actionCall actionHandler) { +func handle(h *sdk.Handler, name string, actionCall actionHandler) { h.HandleFunc(name, func(w http.ResponseWriter, r *http.Request) { var req Request if err := sdk.DecodeRequest(w, r, &req); err != nil { @@ -135,7 +136,7 @@ func (h *Handler) handle(name string, actionCall actionHandler) { }) } -func (h *Handler) handleMount(name string, actionCall mountActionHandler) { +func handleMount(h *sdk.Handler, name string, actionCall mountActionHandler) { h.HandleFunc(name, func(w http.ResponseWriter, r *http.Request) { var req MountRequest if err := sdk.DecodeRequest(w, r, &req); err != nil { @@ -147,7 +148,7 @@ func (h *Handler) handleMount(name string, actionCall mountActionHandler) { }) } -func (h *Handler) handleUnmount(name string, actionCall unmountActionHandler) { +func handleUnmount(h *sdk.Handler, name string, actionCall unmountActionHandler) { h.HandleFunc(name, func(w http.ResponseWriter, r *http.Request) { var req UnmountRequest if err := sdk.DecodeRequest(w, r, &req); err != nil { diff --git a/volume/shim/shim.go b/volume/shim/shim.go index 3086f79..7b53c65 100644 --- a/volume/shim/shim.go +++ b/volume/shim/shim.go @@ -2,6 +2,7 @@ package shim import ( "github.com/docker/docker/volume" + "github.com/docker/go-plugins-helpers/sdk" volumeplugin "github.com/docker/go-plugins-helpers/volume" ) @@ -14,7 +15,7 @@ type shimDriver struct { // to Docker Engine and it would create a plugin from it that maps plugin API calls // directly to any volume driver that satifies the volume.Driver interface from // Docker Engine. -func NewHandlerFromVolumeDriver(d volume.Driver) *volumeplugin.Handler { +func NewHandlerFromVolumeDriver(d volume.Driver) *sdk.Handler { return volumeplugin.NewHandler(&shimDriver{d}) }