diff --git a/api/server/router/build/build.go b/api/server/router/build/build.go index 166f97bc66..dc85d1df00 100644 --- a/api/server/router/build/build.go +++ b/api/server/router/build/build.go @@ -1,9 +1,6 @@ package build -import ( - "github.com/docker/docker/api/server/router" - "github.com/docker/docker/api/server/router/local" -) +import "github.com/docker/docker/api/server/router" // buildRouter is a router to talk with the build controller type buildRouter struct { @@ -27,6 +24,6 @@ func (r *buildRouter) Routes() []router.Route { func (r *buildRouter) initRoutes() { r.routes = []router.Route{ - local.NewPostRoute("/build", r.postBuild), + router.NewPostRoute("/build", r.postBuild), } } diff --git a/api/server/router/container/backend.go b/api/server/router/container/backend.go index 80bed6442e..145a1b7424 100644 --- a/api/server/router/container/backend.go +++ b/api/server/router/container/backend.go @@ -4,11 +4,11 @@ import ( "io" "time" - "github.com/docker/docker/daemon" "github.com/docker/docker/daemon/exec" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/version" "github.com/docker/engine-api/types" + "github.com/docker/engine-api/types/backend" "github.com/docker/engine-api/types/container" ) @@ -51,17 +51,17 @@ type stateBackend interface { type monitorBackend interface { ContainerChanges(name string) ([]archive.Change, error) ContainerInspect(name string, size bool, version version.Version) (interface{}, error) - ContainerLogs(name string, config *daemon.ContainerLogsConfig) error - ContainerStats(name string, config *daemon.ContainerStatsConfig) error + ContainerLogs(name string, config *backend.ContainerLogsConfig) error + ContainerStats(name string, config *backend.ContainerStatsConfig) error ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error) - Containers(config *daemon.ContainersConfig) ([]*types.Container, error) + Containers(config *backend.ContainersConfig) ([]*types.Container, error) } // attachBackend includes function to implement to provide container attaching functionality. type attachBackend interface { - ContainerAttachWithLogs(name string, c *daemon.ContainerAttachWithLogsConfig) error - ContainerWsAttachWithLogs(name string, c *daemon.ContainerWsAttachWithLogsConfig) error + ContainerAttachWithLogs(name string, c *backend.ContainerAttachWithLogsConfig) error + ContainerWsAttachWithLogs(name string, c *backend.ContainerWsAttachWithLogsConfig) error } // Backend is all the methods that need to be implemented to provide container specific functionality. diff --git a/api/server/router/container/container.go b/api/server/router/container/container.go index dd931650dd..873f13d295 100644 --- a/api/server/router/container/container.go +++ b/api/server/router/container/container.go @@ -1,9 +1,6 @@ package container -import ( - "github.com/docker/docker/api/server/router" - "github.com/docker/docker/api/server/router/local" -) +import "github.com/docker/docker/api/server/router" // containerRouter is a router to talk with the container controller type containerRouter struct { @@ -20,7 +17,7 @@ func NewRouter(b Backend) router.Router { return r } -// Routes returns the available routers to the container controller +// Routes returns the available routes to the container controller func (r *containerRouter) Routes() []router.Route { return r.routes } @@ -29,38 +26,38 @@ func (r *containerRouter) Routes() []router.Route { func (r *containerRouter) initRoutes() { r.routes = []router.Route{ // HEAD - local.NewHeadRoute("/containers/{name:.*}/archive", r.headContainersArchive), + router.NewHeadRoute("/containers/{name:.*}/archive", r.headContainersArchive), // GET - local.NewGetRoute("/containers/json", r.getContainersJSON), - local.NewGetRoute("/containers/{name:.*}/export", r.getContainersExport), - local.NewGetRoute("/containers/{name:.*}/changes", r.getContainersChanges), - local.NewGetRoute("/containers/{name:.*}/json", r.getContainersByName), - local.NewGetRoute("/containers/{name:.*}/top", r.getContainersTop), - local.NewGetRoute("/containers/{name:.*}/logs", r.getContainersLogs), - local.NewGetRoute("/containers/{name:.*}/stats", r.getContainersStats), - local.NewGetRoute("/containers/{name:.*}/attach/ws", r.wsContainersAttach), - local.NewGetRoute("/exec/{id:.*}/json", r.getExecByID), - local.NewGetRoute("/containers/{name:.*}/archive", r.getContainersArchive), + router.NewGetRoute("/containers/json", r.getContainersJSON), + router.NewGetRoute("/containers/{name:.*}/export", r.getContainersExport), + router.NewGetRoute("/containers/{name:.*}/changes", r.getContainersChanges), + router.NewGetRoute("/containers/{name:.*}/json", r.getContainersByName), + router.NewGetRoute("/containers/{name:.*}/top", r.getContainersTop), + router.NewGetRoute("/containers/{name:.*}/logs", r.getContainersLogs), + router.NewGetRoute("/containers/{name:.*}/stats", r.getContainersStats), + router.NewGetRoute("/containers/{name:.*}/attach/ws", r.wsContainersAttach), + router.NewGetRoute("/exec/{id:.*}/json", r.getExecByID), + router.NewGetRoute("/containers/{name:.*}/archive", r.getContainersArchive), // POST - local.NewPostRoute("/containers/create", r.postContainersCreate), - local.NewPostRoute("/containers/{name:.*}/kill", r.postContainersKill), - local.NewPostRoute("/containers/{name:.*}/pause", r.postContainersPause), - local.NewPostRoute("/containers/{name:.*}/unpause", r.postContainersUnpause), - local.NewPostRoute("/containers/{name:.*}/restart", r.postContainersRestart), - local.NewPostRoute("/containers/{name:.*}/start", r.postContainersStart), - local.NewPostRoute("/containers/{name:.*}/stop", r.postContainersStop), - local.NewPostRoute("/containers/{name:.*}/wait", r.postContainersWait), - local.NewPostRoute("/containers/{name:.*}/resize", r.postContainersResize), - local.NewPostRoute("/containers/{name:.*}/attach", r.postContainersAttach), - local.NewPostRoute("/containers/{name:.*}/copy", r.postContainersCopy), - local.NewPostRoute("/containers/{name:.*}/exec", r.postContainerExecCreate), - local.NewPostRoute("/exec/{name:.*}/start", r.postContainerExecStart), - local.NewPostRoute("/exec/{name:.*}/resize", r.postContainerExecResize), - local.NewPostRoute("/containers/{name:.*}/rename", r.postContainerRename), - local.NewPostRoute("/containers/{name:.*}/update", r.postContainerUpdate), + router.NewPostRoute("/containers/create", r.postContainersCreate), + router.NewPostRoute("/containers/{name:.*}/kill", r.postContainersKill), + router.NewPostRoute("/containers/{name:.*}/pause", r.postContainersPause), + router.NewPostRoute("/containers/{name:.*}/unpause", r.postContainersUnpause), + router.NewPostRoute("/containers/{name:.*}/restart", r.postContainersRestart), + router.NewPostRoute("/containers/{name:.*}/start", r.postContainersStart), + router.NewPostRoute("/containers/{name:.*}/stop", r.postContainersStop), + router.NewPostRoute("/containers/{name:.*}/wait", r.postContainersWait), + router.NewPostRoute("/containers/{name:.*}/resize", r.postContainersResize), + router.NewPostRoute("/containers/{name:.*}/attach", r.postContainersAttach), + router.NewPostRoute("/containers/{name:.*}/copy", r.postContainersCopy), + router.NewPostRoute("/containers/{name:.*}/exec", r.postContainerExecCreate), + router.NewPostRoute("/exec/{name:.*}/start", r.postContainerExecStart), + router.NewPostRoute("/exec/{name:.*}/resize", r.postContainerExecResize), + router.NewPostRoute("/containers/{name:.*}/rename", r.postContainerRename), + router.NewPostRoute("/containers/{name:.*}/update", r.postContainerUpdate), // PUT - local.NewPutRoute("/containers/{name:.*}/archive", r.putContainersArchive), + router.NewPutRoute("/containers/{name:.*}/archive", r.putContainersArchive), // DELETE - local.NewDeleteRoute("/containers/{name:.*}", r.deleteContainers), + router.NewDeleteRoute("/containers/{name:.*}", r.deleteContainers), } } diff --git a/api/server/router/container/container_routes.go b/api/server/router/container/container_routes.go index 4e2ffca29b..cd429e1d72 100644 --- a/api/server/router/container/container_routes.go +++ b/api/server/router/container/container_routes.go @@ -13,7 +13,6 @@ import ( "github.com/Sirupsen/logrus" "github.com/docker/distribution/registry/api/errcode" "github.com/docker/docker/api/server/httputils" - "github.com/docker/docker/daemon" derr "github.com/docker/docker/errors" "github.com/docker/docker/pkg/ioutils" "github.com/docker/docker/pkg/signal" @@ -21,6 +20,7 @@ import ( "github.com/docker/docker/runconfig" "github.com/docker/docker/utils" "github.com/docker/engine-api/types" + "github.com/docker/engine-api/types/backend" "github.com/docker/engine-api/types/container" timetypes "github.com/docker/engine-api/types/time" "golang.org/x/net/context" @@ -32,7 +32,7 @@ func (s *containerRouter) getContainersJSON(ctx context.Context, w http.Response return err } - config := &daemon.ContainersConfig{ + config := &backend.ContainersConfig{ All: httputils.BoolValue(r, "all"), Size: httputils.BoolValue(r, "size"), Since: r.Form.Get("since"), @@ -77,11 +77,11 @@ func (s *containerRouter) getContainersStats(ctx context.Context, w http.Respons closeNotifier = notifier.CloseNotify() } - config := &daemon.ContainerStatsConfig{ + config := &backend.ContainerStatsConfig{ Stream: stream, OutStream: out, Stop: closeNotifier, - Version: httputils.VersionFromContext(ctx), + Version: string(httputils.VersionFromContext(ctx)), } return s.backend.ContainerStats(vars["name"], config) @@ -133,7 +133,7 @@ func (s *containerRouter) getContainersLogs(ctx context.Context, w http.Response output := ioutils.NewWriteFlusher(w) defer output.Close() - logsConfig := &daemon.ContainerLogsConfig{ + logsConfig := &backend.ContainerLogsConfig{ Follow: httputils.BoolValue(r, "follow"), Timestamps: httputils.BoolValue(r, "timestamps"), Since: since, @@ -446,7 +446,7 @@ func (s *containerRouter) postContainersAttach(ctx context.Context, w http.Respo } } - attachWithLogsConfig := &daemon.ContainerAttachWithLogsConfig{ + attachWithLogsConfig := &backend.ContainerAttachWithLogsConfig{ Hijacker: w.(http.Hijacker), Upgrade: upgrade, UseStdin: httputils.BoolValue(r, "stdin"), @@ -483,7 +483,7 @@ func (s *containerRouter) wsContainersAttach(ctx context.Context, w http.Respons h := websocket.Handler(func(ws *websocket.Conn) { defer ws.Close() - wsAttachWithLogsConfig := &daemon.ContainerWsAttachWithLogsConfig{ + wsAttachWithLogsConfig := &backend.ContainerWsAttachWithLogsConfig{ InStream: ws, OutStream: ws, ErrStream: ws, diff --git a/api/server/router/image/backend.go b/api/server/router/image/backend.go new file mode 100644 index 0000000000..e312307d93 --- /dev/null +++ b/api/server/router/image/backend.go @@ -0,0 +1,44 @@ +package image + +import ( + "io" + + "github.com/docker/docker/reference" + "github.com/docker/engine-api/types" + "github.com/docker/engine-api/types/container" + "github.com/docker/engine-api/types/registry" +) + +// Backend is all the methods that need to be implemented +// to provide image specific functionality. +type Backend interface { + containerBackend + imageBackend + importExportBackend + registryBackend +} + +type containerBackend interface { + Commit(name string, config *types.ContainerCommitConfig) (imageID string, err error) + Exists(containerName string) bool +} + +type imageBackend interface { + ImageDelete(imageRef string, force, prune bool) ([]types.ImageDelete, error) + ImageHistory(imageName string) ([]*types.ImageHistory, error) + Images(filterArgs string, filter string, all bool) ([]*types.Image, error) + LookupImage(name string) (*types.ImageInspect, error) + TagImage(newTag reference.Named, imageName string) error +} + +type importExportBackend interface { + LoadImage(inTar io.ReadCloser, outStream io.Writer) error + ImportImage(src string, newRef reference.Named, msg string, inConfig io.ReadCloser, outStream io.Writer, config *container.Config) error + ExportImage(names []string, outStream io.Writer) error +} + +type registryBackend interface { + PullImage(ref reference.Named, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error + PushImage(ref reference.Named, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error + SearchRegistryForImages(term string, authConfig *types.AuthConfig, metaHeaders map[string][]string) (*registry.SearchResults, error) +} diff --git a/api/server/router/image/image.go b/api/server/router/image/image.go new file mode 100644 index 0000000000..e1b6bed9d7 --- /dev/null +++ b/api/server/router/image/image.go @@ -0,0 +1,44 @@ +package image + +import "github.com/docker/docker/api/server/router" + +// imageRouter is a router to talk with the image controller +type imageRouter struct { + daemon Backend + routes []router.Route +} + +// NewRouter initializes a new image router +func NewRouter(daemon Backend) router.Router { + r := &imageRouter{ + daemon: daemon, + } + r.initRoutes() + return r +} + +// Routes returns the available routes to the image controller +func (r *imageRouter) Routes() []router.Route { + return r.routes +} + +// initRoutes initializes the routes in the image router +func (r *imageRouter) initRoutes() { + r.routes = []router.Route{ + // GET + router.NewGetRoute("/images/json", r.getImagesJSON), + router.NewGetRoute("/images/search", r.getImagesSearch), + router.NewGetRoute("/images/get", r.getImagesGet), + router.NewGetRoute("/images/{name:.*}/get", r.getImagesGet), + router.NewGetRoute("/images/{name:.*}/history", r.getImagesHistory), + router.NewGetRoute("/images/{name:.*}/json", r.getImagesByName), + // POST + router.NewPostRoute("/commit", r.postCommit), + router.NewPostRoute("/images/create", r.postImagesCreate), + router.NewPostRoute("/images/load", r.postImagesLoad), + router.NewPostRoute("/images/{name:.*}/push", r.postImagesPush), + router.NewPostRoute("/images/{name:.*}/tag", r.postImagesTag), + // DELETE + router.NewDeleteRoute("/images/{name:.*}", r.deleteImages), + } +} diff --git a/api/server/router/local/image.go b/api/server/router/image/image_routes.go similarity index 88% rename from api/server/router/local/image.go rename to api/server/router/image/image_routes.go index 3427649f59..bf95d5592f 100644 --- a/api/server/router/local/image.go +++ b/api/server/router/image/image_routes.go @@ -1,4 +1,4 @@ -package local +package image import ( "encoding/base64" @@ -24,7 +24,7 @@ import ( "golang.org/x/net/context" ) -func (s *router) postCommit(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { +func (s *imageRouter) postCommit(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := httputils.ParseForm(r); err != nil { return err } @@ -79,7 +79,7 @@ func (s *router) postCommit(ctx context.Context, w http.ResponseWriter, r *http. } // Creates an image from Pull or from Import -func (s *router) postImagesCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { +func (s *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := httputils.ParseForm(r); err != nil { return err } @@ -188,7 +188,7 @@ func (s *router) postImagesCreate(ctx context.Context, w http.ResponseWriter, r return nil } -func (s *router) postImagesPush(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { +func (s *imageRouter) postImagesPush(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { metaHeaders := map[string][]string{} for k, v := range r.Header { if strings.HasPrefix(k, "X-Meta-") { @@ -243,7 +243,7 @@ func (s *router) postImagesPush(ctx context.Context, w http.ResponseWriter, r *h return nil } -func (s *router) getImagesGet(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { +func (s *imageRouter) getImagesGet(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := httputils.ParseForm(r); err != nil { return err } @@ -278,7 +278,7 @@ func (s *router) postImagesLoad(ctx context.Context, w http.ResponseWriter, r *h return s.daemon.LoadImage(r.Body, w, quiet) } -func (s *router) deleteImages(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { +func (s *imageRouter) deleteImages(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := httputils.ParseForm(r); err != nil { return err } @@ -300,7 +300,7 @@ func (s *router) deleteImages(ctx context.Context, w http.ResponseWriter, r *htt return httputils.WriteJSON(w, http.StatusOK, list) } -func (s *router) getImagesByName(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { +func (s *imageRouter) getImagesByName(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { imageInspect, err := s.daemon.LookupImage(vars["name"]) if err != nil { return err @@ -309,7 +309,7 @@ func (s *router) getImagesByName(ctx context.Context, w http.ResponseWriter, r * return httputils.WriteJSON(w, http.StatusOK, imageInspect) } -func (s *router) getImagesJSON(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { +func (s *imageRouter) getImagesJSON(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := httputils.ParseForm(r); err != nil { return err } @@ -323,7 +323,7 @@ func (s *router) getImagesJSON(ctx context.Context, w http.ResponseWriter, r *ht return httputils.WriteJSON(w, http.StatusOK, images) } -func (s *router) getImagesHistory(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { +func (s *imageRouter) getImagesHistory(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { name := vars["name"] history, err := s.daemon.ImageHistory(name) if err != nil { @@ -333,7 +333,7 @@ func (s *router) getImagesHistory(ctx context.Context, w http.ResponseWriter, r return httputils.WriteJSON(w, http.StatusOK, history) } -func (s *router) postImagesTag(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { +func (s *imageRouter) postImagesTag(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := httputils.ParseForm(r); err != nil { return err } @@ -355,7 +355,7 @@ func (s *router) postImagesTag(ctx context.Context, w http.ResponseWriter, r *ht return nil } -func (s *router) getImagesSearch(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { +func (s *imageRouter) getImagesSearch(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if err := httputils.ParseForm(r); err != nil { return err } diff --git a/api/server/router/local.go b/api/server/router/local.go new file mode 100644 index 0000000000..99db4242b3 --- /dev/null +++ b/api/server/router/local.go @@ -0,0 +1,61 @@ +package router + +import "github.com/docker/docker/api/server/httputils" + +// localRoute defines an individual API route to connect +// with the docker daemon. It implements Route. +type localRoute struct { + method string + path string + handler httputils.APIFunc +} + +// Handler returns the APIFunc to let the server wrap it in middlewares. +func (l localRoute) Handler() httputils.APIFunc { + return l.handler +} + +// Method returns the http method that the route responds to. +func (l localRoute) Method() string { + return l.method +} + +// Path returns the subpath where the route responds to. +func (l localRoute) Path() string { + return l.path +} + +// NewRoute initializes a new local route for the router. +func NewRoute(method, path string, handler httputils.APIFunc) Route { + return localRoute{method, path, handler} +} + +// NewGetRoute initializes a new route with the http method GET. +func NewGetRoute(path string, handler httputils.APIFunc) Route { + return NewRoute("GET", path, handler) +} + +// NewPostRoute initializes a new route with the http method POST. +func NewPostRoute(path string, handler httputils.APIFunc) Route { + return NewRoute("POST", path, handler) +} + +// NewPutRoute initializes a new route with the http method PUT. +func NewPutRoute(path string, handler httputils.APIFunc) Route { + return NewRoute("PUT", path, handler) +} + +// NewDeleteRoute initializes a new route with the http method DELETE. +func NewDeleteRoute(path string, handler httputils.APIFunc) Route { + return NewRoute("DELETE", path, handler) +} + +// NewOptionsRoute initializes a new route with the http method OPTIONS. +func NewOptionsRoute(path string, handler httputils.APIFunc) Route { + return NewRoute("OPTIONS", path, handler) +} + +// NewHeadRoute initializes a new route with the http method HEAD. +func NewHeadRoute(path string, handler httputils.APIFunc) Route { + return NewRoute("HEAD", path, handler) +} diff --git a/api/server/router/local/local.go b/api/server/router/local/local.go deleted file mode 100644 index ed07f97786..0000000000 --- a/api/server/router/local/local.go +++ /dev/null @@ -1,107 +0,0 @@ -package local - -import ( - "github.com/docker/docker/api/server/httputils" - dkrouter "github.com/docker/docker/api/server/router" - "github.com/docker/docker/daemon" -) - -// router is a docker router that talks with the local docker daemon. -type router struct { - daemon *daemon.Daemon - routes []dkrouter.Route -} - -// localRoute defines an individual API route to connect with the docker daemon. -// It implements router.Route. -type localRoute struct { - method string - path string - handler httputils.APIFunc -} - -// Handler returns the APIFunc to let the server wrap it in middlewares -func (l localRoute) Handler() httputils.APIFunc { - return l.handler -} - -// Method returns the http method that the route responds to. -func (l localRoute) Method() string { - return l.method -} - -// Path returns the subpath where the route responds to. -func (l localRoute) Path() string { - return l.path -} - -// NewRoute initializes a new local router for the reouter -func NewRoute(method, path string, handler httputils.APIFunc) dkrouter.Route { - return localRoute{method, path, handler} -} - -// NewGetRoute initializes a new route with the http method GET. -func NewGetRoute(path string, handler httputils.APIFunc) dkrouter.Route { - return NewRoute("GET", path, handler) -} - -// NewPostRoute initializes a new route with the http method POST. -func NewPostRoute(path string, handler httputils.APIFunc) dkrouter.Route { - return NewRoute("POST", path, handler) -} - -// NewPutRoute initializes a new route with the http method PUT. -func NewPutRoute(path string, handler httputils.APIFunc) dkrouter.Route { - return NewRoute("PUT", path, handler) -} - -// NewDeleteRoute initializes a new route with the http method DELETE. -func NewDeleteRoute(path string, handler httputils.APIFunc) dkrouter.Route { - return NewRoute("DELETE", path, handler) -} - -// NewOptionsRoute initializes a new route with the http method OPTIONS -func NewOptionsRoute(path string, handler httputils.APIFunc) dkrouter.Route { - return NewRoute("OPTIONS", path, handler) -} - -// NewHeadRoute initializes a new route with the http method HEAD. -func NewHeadRoute(path string, handler httputils.APIFunc) dkrouter.Route { - return NewRoute("HEAD", path, handler) -} - -// NewRouter initializes a local router with a new daemon. -func NewRouter(daemon *daemon.Daemon) dkrouter.Router { - r := &router{ - daemon: daemon, - } - r.initRoutes() - return r -} - -// Routes returns the list of routes registered in the router. -func (r *router) Routes() []dkrouter.Route { - return r.routes -} - -// initRoutes initializes the routes in this router -func (r *router) initRoutes() { - r.routes = []dkrouter.Route{ - // OPTIONS - // GET - NewGetRoute("/images/json", r.getImagesJSON), - NewGetRoute("/images/search", r.getImagesSearch), - NewGetRoute("/images/get", r.getImagesGet), - NewGetRoute("/images/{name:.*}/get", r.getImagesGet), - NewGetRoute("/images/{name:.*}/history", r.getImagesHistory), - NewGetRoute("/images/{name:.*}/json", r.getImagesByName), - // POST - NewPostRoute("/commit", r.postCommit), - NewPostRoute("/images/create", r.postImagesCreate), - NewPostRoute("/images/load", r.postImagesLoad), - NewPostRoute("/images/{name:.*}/push", r.postImagesPush), - NewPostRoute("/images/{name:.*}/tag", r.postImagesTag), - // DELETE - NewDeleteRoute("/images/{name:.*}", r.deleteImages), - } -} diff --git a/api/server/router/network/backend.go b/api/server/router/network/backend.go index c6ea0adcf8..113c497ce1 100644 --- a/api/server/router/network/backend.go +++ b/api/server/router/network/backend.go @@ -5,18 +5,17 @@ import ( "github.com/docker/libnetwork" ) -// Backend is all the methods that need to be implemented to provide -// network specific functionality +// Backend is all the methods that need to be implemented +// to provide network specific functionality. type Backend interface { + NetworkControllerEnabled() bool + FindNetwork(idName string) (libnetwork.Network, error) - GetNetwork(idName string, by int) (libnetwork.Network, error) + GetNetworkByName(idName string) (libnetwork.Network, error) GetNetworksByID(partialID string) []libnetwork.Network GetAllNetworks() []libnetwork.Network - CreateNetwork(name, driver string, ipam network.IPAM, - options map[string]string, internal bool) (libnetwork.Network, error) + CreateNetwork(name, driver string, ipam network.IPAM, options map[string]string, internal bool) (libnetwork.Network, error) ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error - DisconnectContainerFromNetwork(containerName string, - network libnetwork.Network, force bool) error - NetworkControllerEnabled() bool + DisconnectContainerFromNetwork(containerName string, network libnetwork.Network, force bool) error DeleteNetwork(name string) error } diff --git a/api/server/router/network/network.go b/api/server/router/network/network.go index 5fcb252c2b..59641bc03b 100644 --- a/api/server/router/network/network.go +++ b/api/server/router/network/network.go @@ -5,7 +5,6 @@ import ( "github.com/docker/docker/api/server/httputils" "github.com/docker/docker/api/server/router" - "github.com/docker/docker/api/server/router/local" "github.com/docker/docker/errors" "golang.org/x/net/context" ) @@ -33,14 +32,14 @@ func (r *networkRouter) Routes() []router.Route { func (r *networkRouter) initRoutes() { r.routes = []router.Route{ // GET - local.NewGetRoute("/networks", r.controllerEnabledMiddleware(r.getNetworksList)), - local.NewGetRoute("/networks/{id:.*}", r.controllerEnabledMiddleware(r.getNetwork)), + router.NewGetRoute("/networks", r.controllerEnabledMiddleware(r.getNetworksList)), + router.NewGetRoute("/networks/{id:.*}", r.controllerEnabledMiddleware(r.getNetwork)), // POST - local.NewPostRoute("/networks/create", r.controllerEnabledMiddleware(r.postNetworkCreate)), - local.NewPostRoute("/networks/{id:.*}/connect", r.controllerEnabledMiddleware(r.postNetworkConnect)), - local.NewPostRoute("/networks/{id:.*}/disconnect", r.controllerEnabledMiddleware(r.postNetworkDisconnect)), + router.NewPostRoute("/networks/create", r.controllerEnabledMiddleware(r.postNetworkCreate)), + router.NewPostRoute("/networks/{id:.*}/connect", r.controllerEnabledMiddleware(r.postNetworkConnect)), + router.NewPostRoute("/networks/{id:.*}/disconnect", r.controllerEnabledMiddleware(r.postNetworkDisconnect)), // DELETE - local.NewDeleteRoute("/networks/{id:.*}", r.controllerEnabledMiddleware(r.deleteNetwork)), + router.NewDeleteRoute("/networks/{id:.*}", r.controllerEnabledMiddleware(r.deleteNetwork)), } } diff --git a/api/server/router/network/network_routes.go b/api/server/router/network/network_routes.go index 9798a0b947..25f0e83ca6 100644 --- a/api/server/router/network/network_routes.go +++ b/api/server/router/network/network_routes.go @@ -8,7 +8,6 @@ import ( "golang.org/x/net/context" "github.com/docker/docker/api/server/httputils" - "github.com/docker/docker/daemon" "github.com/docker/docker/runconfig" "github.com/docker/engine-api/types" "github.com/docker/engine-api/types/filters" @@ -81,7 +80,7 @@ func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWr fmt.Sprintf("%s is a pre-defined network and cannot be created", create.Name)) } - nw, err := n.backend.GetNetwork(create.Name, daemon.NetworkByName) + nw, err := n.backend.GetNetworkByName(create.Name) if _, ok := err.(libnetwork.ErrNoSuchNetwork); err != nil && !ok { return err } diff --git a/api/server/router/router.go b/api/server/router/router.go index f3efa82fa6..2de25c27ff 100644 --- a/api/server/router/router.go +++ b/api/server/router/router.go @@ -2,8 +2,9 @@ package router import "github.com/docker/docker/api/server/httputils" -// Router defines an interface to specify a group of routes to add the the docker server. +// Router defines an interface to specify a group of routes to add to the docker server. type Router interface { + // Routes returns the list of routes to add to the docker server. Routes() []Route } diff --git a/api/server/router/system/system.go b/api/server/router/system/system.go index 1bcea2b4f2..76da5c52d5 100644 --- a/api/server/router/system/system.go +++ b/api/server/router/system/system.go @@ -1,37 +1,33 @@ package system -import ( - "github.com/docker/docker/api/server/router" - "github.com/docker/docker/api/server/router/local" -) +import "github.com/docker/docker/api/server/router" -// systemRouter is a Router that provides information about -// the Docker system overall. It gathers information about -// host, daemon and container events. +// systemRouter provides information about the Docker system overall. +// It gathers information about host, daemon and container events. type systemRouter struct { backend Backend routes []router.Route } -// NewRouter initializes a new systemRouter +// NewRouter initializes a new system router func NewRouter(b Backend) router.Router { r := &systemRouter{ backend: b, } r.routes = []router.Route{ - local.NewOptionsRoute("/{anyroute:.*}", optionsHandler), - local.NewGetRoute("/_ping", pingHandler), - local.NewGetRoute("/events", r.getEvents), - local.NewGetRoute("/info", r.getInfo), - local.NewGetRoute("/version", r.getVersion), - local.NewPostRoute("/auth", r.postAuth), + router.NewOptionsRoute("/{anyroute:.*}", optionsHandler), + router.NewGetRoute("/_ping", pingHandler), + router.NewGetRoute("/events", r.getEvents), + router.NewGetRoute("/info", r.getInfo), + router.NewGetRoute("/version", r.getVersion), + router.NewPostRoute("/auth", r.postAuth), } return r } -// Routes return all the API routes dedicated to the docker system. +// Routes returns all the API routes dedicated to the docker system func (s *systemRouter) Routes() []router.Route { return s.routes } diff --git a/api/server/router/volume/volume.go b/api/server/router/volume/volume.go index 8bd5c12906..2683dcec52 100644 --- a/api/server/router/volume/volume.go +++ b/api/server/router/volume/volume.go @@ -1,9 +1,6 @@ package volume -import ( - "github.com/docker/docker/api/server/router" - "github.com/docker/docker/api/server/router/local" -) +import "github.com/docker/docker/api/server/router" // volumeRouter is a router to talk with the volumes controller type volumeRouter struct { @@ -11,7 +8,7 @@ type volumeRouter struct { routes []router.Route } -// NewRouter initializes a new volumeRouter +// NewRouter initializes a new volume router func NewRouter(b Backend) router.Router { r := &volumeRouter{ backend: b, @@ -20,7 +17,7 @@ func NewRouter(b Backend) router.Router { return r } -//Routes returns the available routers to the volumes controller +// Routes returns the available routes to the volumes controller func (r *volumeRouter) Routes() []router.Route { return r.routes } @@ -28,11 +25,11 @@ func (r *volumeRouter) Routes() []router.Route { func (r *volumeRouter) initRoutes() { r.routes = []router.Route{ // GET - local.NewGetRoute("/volumes", r.getVolumesList), - local.NewGetRoute("/volumes/{name:.*}", r.getVolumeByName), + router.NewGetRoute("/volumes", r.getVolumesList), + router.NewGetRoute("/volumes/{name:.*}", r.getVolumeByName), // POST - local.NewPostRoute("/volumes/create", r.postVolumesCreate), + router.NewPostRoute("/volumes/create", r.postVolumesCreate), // DELETE - local.NewDeleteRoute("/volumes/{name:.*}", r.deleteVolumes), + router.NewDeleteRoute("/volumes/{name:.*}", r.deleteVolumes), } } diff --git a/api/server/server.go b/api/server/server.go index a42cd1720b..5e8337a7c2 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -11,7 +11,7 @@ import ( "github.com/docker/docker/api/server/router" "github.com/docker/docker/api/server/router/build" "github.com/docker/docker/api/server/router/container" - "github.com/docker/docker/api/server/router/local" + "github.com/docker/docker/api/server/router/image" "github.com/docker/docker/api/server/router/network" "github.com/docker/docker/api/server/router/system" "github.com/docker/docker/api/server/router/volume" @@ -177,7 +177,7 @@ func (s *Server) makeHTTPHandler(handler httputils.APIFunc) http.HandlerFunc { // InitRouters initializes a list of routers for the server. func (s *Server) InitRouters(d *daemon.Daemon) { s.addRouter(container.NewRouter(d)) - s.addRouter(local.NewRouter(d)) + s.addRouter(image.NewRouter(d)) s.addRouter(network.NewRouter(d)) s.addRouter(system.NewRouter(d)) s.addRouter(volume.NewRouter(d)) diff --git a/daemon/attach.go b/daemon/attach.go index f0caf16996..aabc77082a 100644 --- a/daemon/attach.go +++ b/daemon/attach.go @@ -3,7 +3,6 @@ package daemon import ( "fmt" "io" - "net/http" "time" "github.com/Sirupsen/logrus" @@ -11,22 +10,11 @@ import ( "github.com/docker/docker/daemon/logger" derr "github.com/docker/docker/errors" "github.com/docker/docker/pkg/stdcopy" + "github.com/docker/engine-api/types/backend" ) -// ContainerAttachWithLogsConfig holds the streams to use when connecting to a container to view logs. -type ContainerAttachWithLogsConfig struct { - Hijacker http.Hijacker - Upgrade bool - UseStdin bool - UseStdout bool - UseStderr bool - Logs bool - Stream bool - DetachKeys []byte -} - // ContainerAttachWithLogs attaches to logs according to the config passed in. See ContainerAttachWithLogsConfig. -func (daemon *Daemon) ContainerAttachWithLogs(prefixOrName string, c *ContainerAttachWithLogsConfig) error { +func (daemon *Daemon) ContainerAttachWithLogs(prefixOrName string, c *backend.ContainerAttachWithLogsConfig) error { if c.Hijacker == nil { return derr.ErrorCodeNoHijackConnection.WithArgs(prefixOrName) } @@ -82,17 +70,8 @@ func (daemon *Daemon) ContainerAttachWithLogs(prefixOrName string, c *ContainerA return nil } -// ContainerWsAttachWithLogsConfig attach with websockets, since all -// stream data is delegated to the websocket to handle there. -type ContainerWsAttachWithLogsConfig struct { - InStream io.ReadCloser - OutStream, ErrStream io.Writer - Logs, Stream bool - DetachKeys []byte -} - // ContainerWsAttachWithLogs websocket connection -func (daemon *Daemon) ContainerWsAttachWithLogs(prefixOrName string, c *ContainerWsAttachWithLogsConfig) error { +func (daemon *Daemon) ContainerWsAttachWithLogs(prefixOrName string, c *backend.ContainerWsAttachWithLogsConfig) error { container, err := daemon.GetContainer(prefixOrName) if err != nil { return err diff --git a/daemon/list.go b/daemon/list.go index c363814cfb..5761ca40c5 100644 --- a/daemon/list.go +++ b/daemon/list.go @@ -10,6 +10,7 @@ import ( "github.com/docker/docker/container" "github.com/docker/docker/image" "github.com/docker/engine-api/types" + "github.com/docker/engine-api/types/backend" "github.com/docker/engine-api/types/filters" networktypes "github.com/docker/engine-api/types/network" "github.com/docker/go-connections/nat" @@ -43,24 +44,8 @@ func (daemon *Daemon) List() []*container.Container { return daemon.containers.List() } -// ContainersConfig is the filtering specified by the user to iterate over containers. -type ContainersConfig struct { - // if true show all containers, otherwise only running containers. - All bool - // show all containers created after this container id - Since string - // show all containers created before this container id - Before string - // number of containers to return at most - Limit int - // if true include the sizes of the containers - Size bool - // return only containers that match filters - Filters string -} - // listContext is the daemon generated filtering to iterate over containers. -// This is created based on the user specification. +// This is created based on the user specification from backend.ContainersConfig. type listContext struct { // idx is the container iteration index for this context idx int @@ -81,16 +66,16 @@ type listContext struct { // this is used for --filter=since= and --since=, the latter is deprecated. sinceFilter *container.Container // ContainersConfig is the filters set by the user - *ContainersConfig + *backend.ContainersConfig } // Containers returns the list of containers to show given the user's filtering. -func (daemon *Daemon) Containers(config *ContainersConfig) ([]*types.Container, error) { +func (daemon *Daemon) Containers(config *backend.ContainersConfig) ([]*types.Container, error) { return daemon.reduceContainers(config, daemon.transformContainer) } -// reduceContainer parses the user filtering and generates the list of containers to return based on a reducer. -func (daemon *Daemon) reduceContainers(config *ContainersConfig, reducer containerReducer) ([]*types.Container, error) { +// reduceContainers parses the user's filtering options and generates the list of containers to return based on a reducer. +func (daemon *Daemon) reduceContainers(config *backend.ContainersConfig, reducer containerReducer) ([]*types.Container, error) { containers := []*types.Container{} ctx, err := daemon.foldFilter(config) @@ -132,8 +117,8 @@ func (daemon *Daemon) reducePsContainer(container *container.Container, ctx *lis return reducer(container, ctx) } -// foldFilter generates the container filter based in the user's filtering options. -func (daemon *Daemon) foldFilter(config *ContainersConfig) (*listContext, error) { +// foldFilter generates the container filter based on the user's filtering options. +func (daemon *Daemon) foldFilter(config *backend.ContainersConfig) (*listContext, error) { psFilters, err := filters.FromParam(config.Filters) if err != nil { return nil, err diff --git a/daemon/logs.go b/daemon/logs.go index b10f7df769..bb6586f272 100644 --- a/daemon/logs.go +++ b/daemon/logs.go @@ -3,7 +3,6 @@ package daemon import ( "io" "strconv" - "time" "github.com/Sirupsen/logrus" "github.com/docker/docker/container" @@ -11,28 +10,12 @@ import ( "github.com/docker/docker/daemon/logger/jsonfilelog" derr "github.com/docker/docker/errors" "github.com/docker/docker/pkg/stdcopy" + "github.com/docker/engine-api/types/backend" ) -// ContainerLogsConfig holds configs for logging operations. Exists -// for users of the daemon to to pass it a logging configuration. -type ContainerLogsConfig struct { - // if true stream log output - Follow bool - // if true include timestamps for each line of log output - Timestamps bool - // return that many lines of log output from the end - Tail string - // filter logs by returning on those entries after this time - Since time.Time - // whether or not to show stdout and stderr as well as log entries. - UseStdout, UseStderr bool - OutStream io.Writer - Stop <-chan bool -} - // ContainerLogs hooks up a container's stdout and stderr streams // configured with the given struct. -func (daemon *Daemon) ContainerLogs(containerName string, config *ContainerLogsConfig) error { +func (daemon *Daemon) ContainerLogs(containerName string, config *backend.ContainerLogsConfig) error { container, err := daemon.GetContainer(containerName) if err != nil { return derr.ErrorCodeNoSuchContainer.WithArgs(containerName) diff --git a/daemon/network.go b/daemon/network.go index f6a2515202..07d0771f7c 100644 --- a/daemon/network.go +++ b/daemon/network.go @@ -1,7 +1,6 @@ package daemon import ( - "errors" "fmt" "net" "strings" @@ -12,13 +11,6 @@ import ( "github.com/docker/libnetwork" ) -const ( - // NetworkByID represents a constant to find a network by its ID - NetworkByID = iota + 1 - // NetworkByName represents a constant to find a network by its Name - NetworkByName -) - // NetworkControllerEnabled checks if the networking stack is enabled. // This feature depends on OS primitives and it's disabled in systems like Windows. func (daemon *Daemon) NetworkControllerEnabled() bool { @@ -28,8 +20,8 @@ func (daemon *Daemon) NetworkControllerEnabled() bool { // FindNetwork function finds a network for a given string that can represent network name or id func (daemon *Daemon) FindNetwork(idName string) (libnetwork.Network, error) { // Find by Name - n, err := daemon.GetNetwork(idName, NetworkByName) - if _, ok := err.(libnetwork.ErrNoSuchNetwork); err != nil && !ok { + n, err := daemon.GetNetworkByName(idName) + if err != nil && !isNoSuchNetworkError(err) { return nil, err } @@ -38,38 +30,35 @@ func (daemon *Daemon) FindNetwork(idName string) (libnetwork.Network, error) { } // Find by id - n, err = daemon.GetNetwork(idName, NetworkByID) - if err != nil { - return nil, err - } - - return n, nil + return daemon.GetNetworkByID(idName) } -// GetNetwork function returns a network for a given string that represents the network and -// a hint to indicate if the string is an Id or Name of the network -func (daemon *Daemon) GetNetwork(idName string, by int) (libnetwork.Network, error) { - c := daemon.netController - switch by { - case NetworkByID: - list := daemon.GetNetworksByID(idName) +func isNoSuchNetworkError(err error) bool { + _, ok := err.(libnetwork.ErrNoSuchNetwork) + return ok +} - if len(list) == 0 { - return nil, libnetwork.ErrNoSuchNetwork(idName) - } +// GetNetworkByID function returns a network whose ID begins with the given prefix. +// It fails with an error if no matching, or more than one matching, networks are found. +func (daemon *Daemon) GetNetworkByID(partialID string) (libnetwork.Network, error) { + list := daemon.GetNetworksByID(partialID) - if len(list) > 1 { - return nil, libnetwork.ErrInvalidID(idName) - } - - return list[0], nil - case NetworkByName: - if idName == "" { - idName = c.Config().Daemon.DefaultNetwork - } - return c.NetworkByName(idName) + if len(list) == 0 { + return nil, libnetwork.ErrNoSuchNetwork(partialID) } - return nil, errors.New("unexpected selector for GetNetwork") + if len(list) > 1 { + return nil, libnetwork.ErrInvalidID(partialID) + } + return list[0], nil +} + +// GetNetworkByName function returns a network for a given network name. +func (daemon *Daemon) GetNetworkByName(name string) (libnetwork.Network, error) { + c := daemon.netController + if name == "" { + name = c.Config().Daemon.DefaultNetwork + } + return c.NetworkByName(name) } // GetNetworksByID returns a list of networks whose ID partially matches zero or more networks diff --git a/daemon/stats.go b/daemon/stats.go index a3155165e9..a1e41283d8 100644 --- a/daemon/stats.go +++ b/daemon/stats.go @@ -3,30 +3,23 @@ package daemon import ( "encoding/json" "errors" - "io" "runtime" "github.com/docker/docker/daemon/execdriver" "github.com/docker/docker/pkg/version" "github.com/docker/engine-api/types" + "github.com/docker/engine-api/types/backend" "github.com/docker/engine-api/types/versions/v1p20" ) -// ContainerStatsConfig holds information for configuring the runtime -// behavior of a daemon.ContainerStats() call. -type ContainerStatsConfig struct { - Stream bool - OutStream io.Writer - Stop <-chan bool - Version version.Version -} - // ContainerStats writes information about the container to the stream // given in the config object. -func (daemon *Daemon) ContainerStats(prefixOrName string, config *ContainerStatsConfig) error { +func (daemon *Daemon) ContainerStats(prefixOrName string, config *backend.ContainerStatsConfig) error { if runtime.GOOS == "windows" { return errors.New("Windows does not support stats") } + // Remote API version (used for backwards compatibility) + apiVersion := version.Version(config.Version) container, err := daemon.GetContainer(prefixOrName) if err != nil { @@ -72,7 +65,7 @@ func (daemon *Daemon) ContainerStats(prefixOrName string, config *ContainerStats var statsJSON interface{} statsJSONPost120 := getStatJSON(v) - if config.Version.LessThan("1.21") { + if apiVersion.LessThan("1.21") { var ( rxBytes uint64 rxPackets uint64