Decouple the "container" router from the actual daemon implementation.

This is done by moving the following types to api/types/config.go:
  - ContainersConfig
  - ContainerAttachWithLogsConfig
  - ContainerWsAttachWithLogsConfig
  - ContainerLogsConfig
  - ContainerStatsConfig

Remove dependency on "version" package from types.ContainerStatsConfig.
Decouple the "container" router from the "daemon/exec" implementation.

* This is done by making daemon.ContainerExecInspect() return an interface{}
value. The same trick is already used by daemon.ContainerInspect().

Improve documentation for router packages.
Extract localRoute and router into separate files.
Move local.router to image.imageRouter.

Changes:
  - Move local/image.go to image/image_routes.go.
  - Move local/local.go to image/image.go
  - Rename router to imageRouter.
  - Simplify imports for image/image.go (remove alias for router package).

Merge router/local package into router package.
Decouple the "image" router from the actual daemon implementation.
Add Daemon.GetNetworkByID and Daemon.GetNetworkByName.
Decouple the "network" router from the actual daemon implementation.

This is done by replacing the daemon.NetworkByName constant with
an explicit GetNetworkByName method.

Remove the unused Daemon.GetNetwork method and the associated constants NetworkByID and NetworkByName.

Signed-off-by: Lukas Waslowski <cr7pt0gr4ph7@gmail.com>
Signed-off-by: David Calavera <david.calavera@gmail.com>
This commit is contained in:
Lukas Waslowski 2015-12-30 18:20:41 +01:00 committed by David Calavera
parent e6573a5d18
commit dd93571c69
21 changed files with 286 additions and 330 deletions

View File

@ -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),
}
}

View File

@ -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.

View File

@ -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),
}
}

View File

@ -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,

View File

@ -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)
}

View File

@ -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),
}
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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),
}
}

View File

@ -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
}

View File

@ -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)),
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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),
}
}

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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