mirror of https://github.com/docker/docs.git
Merge pull request #19772 from calavera/decouple-server-routers
[Carry 19133] Decouple server routers from the daemon package.
This commit is contained in:
commit
8c6887c54d
|
@ -1,9 +1,6 @@
|
||||||
package build
|
package build
|
||||||
|
|
||||||
import (
|
import "github.com/docker/docker/api/server/router"
|
||||||
"github.com/docker/docker/api/server/router"
|
|
||||||
"github.com/docker/docker/api/server/router/local"
|
|
||||||
)
|
|
||||||
|
|
||||||
// buildRouter is a router to talk with the build controller
|
// buildRouter is a router to talk with the build controller
|
||||||
type buildRouter struct {
|
type buildRouter struct {
|
||||||
|
@ -27,6 +24,6 @@ func (r *buildRouter) Routes() []router.Route {
|
||||||
|
|
||||||
func (r *buildRouter) initRoutes() {
|
func (r *buildRouter) initRoutes() {
|
||||||
r.routes = []router.Route{
|
r.routes = []router.Route{
|
||||||
local.NewPostRoute("/build", r.postBuild),
|
router.NewPostRoute("/build", r.postBuild),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/daemon"
|
"github.com/docker/docker/api/types/backend"
|
||||||
"github.com/docker/docker/daemon/exec"
|
"github.com/docker/docker/daemon/exec"
|
||||||
"github.com/docker/docker/pkg/archive"
|
"github.com/docker/docker/pkg/archive"
|
||||||
"github.com/docker/docker/pkg/version"
|
"github.com/docker/docker/pkg/version"
|
||||||
|
@ -51,17 +51,17 @@ type stateBackend interface {
|
||||||
type monitorBackend interface {
|
type monitorBackend interface {
|
||||||
ContainerChanges(name string) ([]archive.Change, error)
|
ContainerChanges(name string) ([]archive.Change, error)
|
||||||
ContainerInspect(name string, size bool, version version.Version) (interface{}, error)
|
ContainerInspect(name string, size bool, version version.Version) (interface{}, error)
|
||||||
ContainerLogs(name string, config *daemon.ContainerLogsConfig) error
|
ContainerLogs(name string, config *backend.ContainerLogsConfig) error
|
||||||
ContainerStats(name string, config *daemon.ContainerStatsConfig) error
|
ContainerStats(name string, config *backend.ContainerStatsConfig) error
|
||||||
ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error)
|
ContainerTop(name string, psArgs string) (*types.ContainerProcessList, error)
|
||||||
|
|
||||||
Containers(config *daemon.ContainersConfig) ([]*types.Container, error)
|
Containers(config *types.ContainerListOptions) ([]*types.Container, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// attachBackend includes function to implement to provide container attaching functionality.
|
// attachBackend includes function to implement to provide container attaching functionality.
|
||||||
type attachBackend interface {
|
type attachBackend interface {
|
||||||
ContainerAttachWithLogs(name string, c *daemon.ContainerAttachWithLogsConfig) error
|
ContainerAttachWithLogs(name string, c *backend.ContainerAttachWithLogsConfig) error
|
||||||
ContainerWsAttachWithLogs(name string, c *daemon.ContainerWsAttachWithLogsConfig) error
|
ContainerWsAttachWithLogs(name string, c *backend.ContainerWsAttachWithLogsConfig) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backend is all the methods that need to be implemented to provide container specific functionality.
|
// Backend is all the methods that need to be implemented to provide container specific functionality.
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import "github.com/docker/docker/api/server/router"
|
||||||
"github.com/docker/docker/api/server/router"
|
|
||||||
"github.com/docker/docker/api/server/router/local"
|
|
||||||
)
|
|
||||||
|
|
||||||
// containerRouter is a router to talk with the container controller
|
// containerRouter is a router to talk with the container controller
|
||||||
type containerRouter struct {
|
type containerRouter struct {
|
||||||
|
@ -20,7 +17,7 @@ func NewRouter(b Backend) router.Router {
|
||||||
return r
|
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 {
|
func (r *containerRouter) Routes() []router.Route {
|
||||||
return r.routes
|
return r.routes
|
||||||
}
|
}
|
||||||
|
@ -29,38 +26,38 @@ func (r *containerRouter) Routes() []router.Route {
|
||||||
func (r *containerRouter) initRoutes() {
|
func (r *containerRouter) initRoutes() {
|
||||||
r.routes = []router.Route{
|
r.routes = []router.Route{
|
||||||
// HEAD
|
// HEAD
|
||||||
local.NewHeadRoute("/containers/{name:.*}/archive", r.headContainersArchive),
|
router.NewHeadRoute("/containers/{name:.*}/archive", r.headContainersArchive),
|
||||||
// GET
|
// GET
|
||||||
local.NewGetRoute("/containers/json", r.getContainersJSON),
|
router.NewGetRoute("/containers/json", r.getContainersJSON),
|
||||||
local.NewGetRoute("/containers/{name:.*}/export", r.getContainersExport),
|
router.NewGetRoute("/containers/{name:.*}/export", r.getContainersExport),
|
||||||
local.NewGetRoute("/containers/{name:.*}/changes", r.getContainersChanges),
|
router.NewGetRoute("/containers/{name:.*}/changes", r.getContainersChanges),
|
||||||
local.NewGetRoute("/containers/{name:.*}/json", r.getContainersByName),
|
router.NewGetRoute("/containers/{name:.*}/json", r.getContainersByName),
|
||||||
local.NewGetRoute("/containers/{name:.*}/top", r.getContainersTop),
|
router.NewGetRoute("/containers/{name:.*}/top", r.getContainersTop),
|
||||||
local.NewGetRoute("/containers/{name:.*}/logs", r.getContainersLogs),
|
router.NewGetRoute("/containers/{name:.*}/logs", r.getContainersLogs),
|
||||||
local.NewGetRoute("/containers/{name:.*}/stats", r.getContainersStats),
|
router.NewGetRoute("/containers/{name:.*}/stats", r.getContainersStats),
|
||||||
local.NewGetRoute("/containers/{name:.*}/attach/ws", r.wsContainersAttach),
|
router.NewGetRoute("/containers/{name:.*}/attach/ws", r.wsContainersAttach),
|
||||||
local.NewGetRoute("/exec/{id:.*}/json", r.getExecByID),
|
router.NewGetRoute("/exec/{id:.*}/json", r.getExecByID),
|
||||||
local.NewGetRoute("/containers/{name:.*}/archive", r.getContainersArchive),
|
router.NewGetRoute("/containers/{name:.*}/archive", r.getContainersArchive),
|
||||||
// POST
|
// POST
|
||||||
local.NewPostRoute("/containers/create", r.postContainersCreate),
|
router.NewPostRoute("/containers/create", r.postContainersCreate),
|
||||||
local.NewPostRoute("/containers/{name:.*}/kill", r.postContainersKill),
|
router.NewPostRoute("/containers/{name:.*}/kill", r.postContainersKill),
|
||||||
local.NewPostRoute("/containers/{name:.*}/pause", r.postContainersPause),
|
router.NewPostRoute("/containers/{name:.*}/pause", r.postContainersPause),
|
||||||
local.NewPostRoute("/containers/{name:.*}/unpause", r.postContainersUnpause),
|
router.NewPostRoute("/containers/{name:.*}/unpause", r.postContainersUnpause),
|
||||||
local.NewPostRoute("/containers/{name:.*}/restart", r.postContainersRestart),
|
router.NewPostRoute("/containers/{name:.*}/restart", r.postContainersRestart),
|
||||||
local.NewPostRoute("/containers/{name:.*}/start", r.postContainersStart),
|
router.NewPostRoute("/containers/{name:.*}/start", r.postContainersStart),
|
||||||
local.NewPostRoute("/containers/{name:.*}/stop", r.postContainersStop),
|
router.NewPostRoute("/containers/{name:.*}/stop", r.postContainersStop),
|
||||||
local.NewPostRoute("/containers/{name:.*}/wait", r.postContainersWait),
|
router.NewPostRoute("/containers/{name:.*}/wait", r.postContainersWait),
|
||||||
local.NewPostRoute("/containers/{name:.*}/resize", r.postContainersResize),
|
router.NewPostRoute("/containers/{name:.*}/resize", r.postContainersResize),
|
||||||
local.NewPostRoute("/containers/{name:.*}/attach", r.postContainersAttach),
|
router.NewPostRoute("/containers/{name:.*}/attach", r.postContainersAttach),
|
||||||
local.NewPostRoute("/containers/{name:.*}/copy", r.postContainersCopy),
|
router.NewPostRoute("/containers/{name:.*}/copy", r.postContainersCopy),
|
||||||
local.NewPostRoute("/containers/{name:.*}/exec", r.postContainerExecCreate),
|
router.NewPostRoute("/containers/{name:.*}/exec", r.postContainerExecCreate),
|
||||||
local.NewPostRoute("/exec/{name:.*}/start", r.postContainerExecStart),
|
router.NewPostRoute("/exec/{name:.*}/start", r.postContainerExecStart),
|
||||||
local.NewPostRoute("/exec/{name:.*}/resize", r.postContainerExecResize),
|
router.NewPostRoute("/exec/{name:.*}/resize", r.postContainerExecResize),
|
||||||
local.NewPostRoute("/containers/{name:.*}/rename", r.postContainerRename),
|
router.NewPostRoute("/containers/{name:.*}/rename", r.postContainerRename),
|
||||||
local.NewPostRoute("/containers/{name:.*}/update", r.postContainerUpdate),
|
router.NewPostRoute("/containers/{name:.*}/update", r.postContainerUpdate),
|
||||||
// PUT
|
// PUT
|
||||||
local.NewPutRoute("/containers/{name:.*}/archive", r.putContainersArchive),
|
router.NewPutRoute("/containers/{name:.*}/archive", r.putContainersArchive),
|
||||||
// DELETE
|
// DELETE
|
||||||
local.NewDeleteRoute("/containers/{name:.*}", r.deleteContainers),
|
router.NewDeleteRoute("/containers/{name:.*}", r.deleteContainers),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/distribution/registry/api/errcode"
|
"github.com/docker/distribution/registry/api/errcode"
|
||||||
"github.com/docker/docker/api/server/httputils"
|
"github.com/docker/docker/api/server/httputils"
|
||||||
"github.com/docker/docker/daemon"
|
"github.com/docker/docker/api/types/backend"
|
||||||
derr "github.com/docker/docker/errors"
|
derr "github.com/docker/docker/errors"
|
||||||
"github.com/docker/docker/pkg/ioutils"
|
"github.com/docker/docker/pkg/ioutils"
|
||||||
"github.com/docker/docker/pkg/signal"
|
"github.com/docker/docker/pkg/signal"
|
||||||
|
@ -22,7 +22,7 @@ import (
|
||||||
"github.com/docker/docker/utils"
|
"github.com/docker/docker/utils"
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
"github.com/docker/engine-api/types/container"
|
"github.com/docker/engine-api/types/container"
|
||||||
timetypes "github.com/docker/engine-api/types/time"
|
"github.com/docker/engine-api/types/filters"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"golang.org/x/net/websocket"
|
"golang.org/x/net/websocket"
|
||||||
)
|
)
|
||||||
|
@ -31,13 +31,17 @@ func (s *containerRouter) getContainersJSON(ctx context.Context, w http.Response
|
||||||
if err := httputils.ParseForm(r); err != nil {
|
if err := httputils.ParseForm(r); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
filter, err := filters.FromParam(r.Form.Get("filters"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
config := &daemon.ContainersConfig{
|
config := &types.ContainerListOptions{
|
||||||
All: httputils.BoolValue(r, "all"),
|
All: httputils.BoolValue(r, "all"),
|
||||||
Size: httputils.BoolValue(r, "size"),
|
Size: httputils.BoolValue(r, "size"),
|
||||||
Since: r.Form.Get("since"),
|
Since: r.Form.Get("since"),
|
||||||
Before: r.Form.Get("before"),
|
Before: r.Form.Get("before"),
|
||||||
Filters: r.Form.Get("filters"),
|
Filter: filter,
|
||||||
}
|
}
|
||||||
|
|
||||||
if tmpLimit := r.Form.Get("limit"); tmpLimit != "" {
|
if tmpLimit := r.Form.Get("limit"); tmpLimit != "" {
|
||||||
|
@ -77,11 +81,11 @@ func (s *containerRouter) getContainersStats(ctx context.Context, w http.Respons
|
||||||
closeNotifier = notifier.CloseNotify()
|
closeNotifier = notifier.CloseNotify()
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &daemon.ContainerStatsConfig{
|
config := &backend.ContainerStatsConfig{
|
||||||
Stream: stream,
|
Stream: stream,
|
||||||
OutStream: out,
|
OutStream: out,
|
||||||
Stop: closeNotifier,
|
Stop: closeNotifier,
|
||||||
Version: httputils.VersionFromContext(ctx),
|
Version: string(httputils.VersionFromContext(ctx)),
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.backend.ContainerStats(vars["name"], config)
|
return s.backend.ContainerStats(vars["name"], config)
|
||||||
|
@ -102,15 +106,6 @@ func (s *containerRouter) getContainersLogs(ctx context.Context, w http.Response
|
||||||
return fmt.Errorf("Bad parameters: you must choose at least one stream")
|
return fmt.Errorf("Bad parameters: you must choose at least one stream")
|
||||||
}
|
}
|
||||||
|
|
||||||
var since time.Time
|
|
||||||
if r.Form.Get("since") != "" {
|
|
||||||
s, n, err := timetypes.ParseTimestamps(r.Form.Get("since"), 0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
since = time.Unix(s, n)
|
|
||||||
}
|
|
||||||
|
|
||||||
var closeNotifier <-chan bool
|
var closeNotifier <-chan bool
|
||||||
if notifier, ok := w.(http.CloseNotifier); ok {
|
if notifier, ok := w.(http.CloseNotifier); ok {
|
||||||
closeNotifier = notifier.CloseNotify()
|
closeNotifier = notifier.CloseNotify()
|
||||||
|
@ -133,15 +128,17 @@ func (s *containerRouter) getContainersLogs(ctx context.Context, w http.Response
|
||||||
output := ioutils.NewWriteFlusher(w)
|
output := ioutils.NewWriteFlusher(w)
|
||||||
defer output.Close()
|
defer output.Close()
|
||||||
|
|
||||||
logsConfig := &daemon.ContainerLogsConfig{
|
logsConfig := &backend.ContainerLogsConfig{
|
||||||
Follow: httputils.BoolValue(r, "follow"),
|
ContainerLogsOptions: types.ContainerLogsOptions{
|
||||||
Timestamps: httputils.BoolValue(r, "timestamps"),
|
Follow: httputils.BoolValue(r, "follow"),
|
||||||
Since: since,
|
Timestamps: httputils.BoolValue(r, "timestamps"),
|
||||||
Tail: r.Form.Get("tail"),
|
Since: r.Form.Get("since"),
|
||||||
UseStdout: stdout,
|
Tail: r.Form.Get("tail"),
|
||||||
UseStderr: stderr,
|
ShowStdout: stdout,
|
||||||
OutStream: output,
|
ShowStderr: stderr,
|
||||||
Stop: closeNotifier,
|
},
|
||||||
|
OutStream: output,
|
||||||
|
Stop: closeNotifier,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.backend.ContainerLogs(containerName, logsConfig); err != nil {
|
if err := s.backend.ContainerLogs(containerName, logsConfig); err != nil {
|
||||||
|
@ -446,7 +443,7 @@ func (s *containerRouter) postContainersAttach(ctx context.Context, w http.Respo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
attachWithLogsConfig := &daemon.ContainerAttachWithLogsConfig{
|
attachWithLogsConfig := &backend.ContainerAttachWithLogsConfig{
|
||||||
Hijacker: w.(http.Hijacker),
|
Hijacker: w.(http.Hijacker),
|
||||||
Upgrade: upgrade,
|
Upgrade: upgrade,
|
||||||
UseStdin: httputils.BoolValue(r, "stdin"),
|
UseStdin: httputils.BoolValue(r, "stdin"),
|
||||||
|
@ -483,7 +480,7 @@ func (s *containerRouter) wsContainersAttach(ctx context.Context, w http.Respons
|
||||||
h := websocket.Handler(func(ws *websocket.Conn) {
|
h := websocket.Handler(func(ws *websocket.Conn) {
|
||||||
defer ws.Close()
|
defer ws.Close()
|
||||||
|
|
||||||
wsAttachWithLogsConfig := &daemon.ContainerWsAttachWithLogsConfig{
|
wsAttachWithLogsConfig := &backend.ContainerWsAttachWithLogsConfig{
|
||||||
InStream: ws,
|
InStream: ws,
|
||||||
OutStream: ws,
|
OutStream: ws,
|
||||||
ErrStream: ws,
|
ErrStream: ws,
|
||||||
|
|
|
@ -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, quiet bool) 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)
|
||||||
|
}
|
|
@ -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),
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package local
|
package image
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
@ -24,7 +24,7 @@ import (
|
||||||
"golang.org/x/net/context"
|
"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 {
|
if err := httputils.ParseForm(r); err != nil {
|
||||||
return err
|
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
|
// 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 {
|
if err := httputils.ParseForm(r); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ func (s *router) postImagesCreate(ctx context.Context, w http.ResponseWriter, r
|
||||||
return nil
|
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{}
|
metaHeaders := map[string][]string{}
|
||||||
for k, v := range r.Header {
|
for k, v := range r.Header {
|
||||||
if strings.HasPrefix(k, "X-Meta-") {
|
if strings.HasPrefix(k, "X-Meta-") {
|
||||||
|
@ -243,7 +243,7 @@ func (s *router) postImagesPush(ctx context.Context, w http.ResponseWriter, r *h
|
||||||
return nil
|
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 {
|
if err := httputils.ParseForm(r); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ func (s *router) getImagesGet(ctx context.Context, w http.ResponseWriter, r *htt
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *router) postImagesLoad(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
func (s *imageRouter) postImagesLoad(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
||||||
if err := httputils.ParseForm(r); err != nil {
|
if err := httputils.ParseForm(r); err != nil {
|
||||||
return err
|
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)
|
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 {
|
if err := httputils.ParseForm(r); err != nil {
|
||||||
return err
|
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)
|
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"])
|
imageInspect, err := s.daemon.LookupImage(vars["name"])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -309,7 +309,7 @@ func (s *router) getImagesByName(ctx context.Context, w http.ResponseWriter, r *
|
||||||
return httputils.WriteJSON(w, http.StatusOK, imageInspect)
|
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 {
|
if err := httputils.ParseForm(r); err != nil {
|
||||||
return err
|
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)
|
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"]
|
name := vars["name"]
|
||||||
history, err := s.daemon.ImageHistory(name)
|
history, err := s.daemon.ImageHistory(name)
|
||||||
if err != nil {
|
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)
|
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 {
|
if err := httputils.ParseForm(r); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -355,7 +355,7 @@ func (s *router) postImagesTag(ctx context.Context, w http.ResponseWriter, r *ht
|
||||||
return nil
|
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 {
|
if err := httputils.ParseForm(r); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
|
@ -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)
|
||||||
|
}
|
|
@ -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),
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,18 +5,17 @@ import (
|
||||||
"github.com/docker/libnetwork"
|
"github.com/docker/libnetwork"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Backend is all the methods that need to be implemented to provide
|
// Backend is all the methods that need to be implemented
|
||||||
// network specific functionality
|
// to provide network specific functionality.
|
||||||
type Backend interface {
|
type Backend interface {
|
||||||
|
NetworkControllerEnabled() bool
|
||||||
|
|
||||||
FindNetwork(idName string) (libnetwork.Network, error)
|
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
|
GetNetworksByID(partialID string) []libnetwork.Network
|
||||||
GetAllNetworks() []libnetwork.Network
|
GetAllNetworks() []libnetwork.Network
|
||||||
CreateNetwork(name, driver string, ipam network.IPAM,
|
CreateNetwork(name, driver string, ipam network.IPAM, options map[string]string, internal bool) (libnetwork.Network, error)
|
||||||
options map[string]string, internal bool) (libnetwork.Network, error)
|
|
||||||
ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error
|
ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error
|
||||||
DisconnectContainerFromNetwork(containerName string,
|
DisconnectContainerFromNetwork(containerName string, network libnetwork.Network, force bool) error
|
||||||
network libnetwork.Network, force bool) error
|
|
||||||
NetworkControllerEnabled() bool
|
|
||||||
DeleteNetwork(name string) error
|
DeleteNetwork(name string) error
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
|
|
||||||
"github.com/docker/docker/api/server/httputils"
|
"github.com/docker/docker/api/server/httputils"
|
||||||
"github.com/docker/docker/api/server/router"
|
"github.com/docker/docker/api/server/router"
|
||||||
"github.com/docker/docker/api/server/router/local"
|
|
||||||
"github.com/docker/docker/errors"
|
"github.com/docker/docker/errors"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
@ -33,14 +32,14 @@ func (r *networkRouter) Routes() []router.Route {
|
||||||
func (r *networkRouter) initRoutes() {
|
func (r *networkRouter) initRoutes() {
|
||||||
r.routes = []router.Route{
|
r.routes = []router.Route{
|
||||||
// GET
|
// GET
|
||||||
local.NewGetRoute("/networks", r.controllerEnabledMiddleware(r.getNetworksList)),
|
router.NewGetRoute("/networks", r.controllerEnabledMiddleware(r.getNetworksList)),
|
||||||
local.NewGetRoute("/networks/{id:.*}", r.controllerEnabledMiddleware(r.getNetwork)),
|
router.NewGetRoute("/networks/{id:.*}", r.controllerEnabledMiddleware(r.getNetwork)),
|
||||||
// POST
|
// POST
|
||||||
local.NewPostRoute("/networks/create", r.controllerEnabledMiddleware(r.postNetworkCreate)),
|
router.NewPostRoute("/networks/create", r.controllerEnabledMiddleware(r.postNetworkCreate)),
|
||||||
local.NewPostRoute("/networks/{id:.*}/connect", r.controllerEnabledMiddleware(r.postNetworkConnect)),
|
router.NewPostRoute("/networks/{id:.*}/connect", r.controllerEnabledMiddleware(r.postNetworkConnect)),
|
||||||
local.NewPostRoute("/networks/{id:.*}/disconnect", r.controllerEnabledMiddleware(r.postNetworkDisconnect)),
|
router.NewPostRoute("/networks/{id:.*}/disconnect", r.controllerEnabledMiddleware(r.postNetworkDisconnect)),
|
||||||
// DELETE
|
// DELETE
|
||||||
local.NewDeleteRoute("/networks/{id:.*}", r.controllerEnabledMiddleware(r.deleteNetwork)),
|
router.NewDeleteRoute("/networks/{id:.*}", r.controllerEnabledMiddleware(r.deleteNetwork)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
"github.com/docker/docker/api/server/httputils"
|
"github.com/docker/docker/api/server/httputils"
|
||||||
"github.com/docker/docker/daemon"
|
|
||||||
"github.com/docker/docker/runconfig"
|
"github.com/docker/docker/runconfig"
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
"github.com/docker/engine-api/types/filters"
|
"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))
|
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 {
|
if _, ok := err.(libnetwork.ErrNoSuchNetwork); err != nil && !ok {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,9 @@ package router
|
||||||
|
|
||||||
import "github.com/docker/docker/api/server/httputils"
|
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 {
|
type Router interface {
|
||||||
|
// Routes returns the list of routes to add to the docker server.
|
||||||
Routes() []Route
|
Routes() []Route
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,37 +1,33 @@
|
||||||
package system
|
package system
|
||||||
|
|
||||||
import (
|
import "github.com/docker/docker/api/server/router"
|
||||||
"github.com/docker/docker/api/server/router"
|
|
||||||
"github.com/docker/docker/api/server/router/local"
|
|
||||||
)
|
|
||||||
|
|
||||||
// systemRouter is a Router that provides information about
|
// systemRouter provides information about the Docker system overall.
|
||||||
// the Docker system overall. It gathers information about
|
// It gathers information about host, daemon and container events.
|
||||||
// host, daemon and container events.
|
|
||||||
type systemRouter struct {
|
type systemRouter struct {
|
||||||
backend Backend
|
backend Backend
|
||||||
routes []router.Route
|
routes []router.Route
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRouter initializes a new systemRouter
|
// NewRouter initializes a new system router
|
||||||
func NewRouter(b Backend) router.Router {
|
func NewRouter(b Backend) router.Router {
|
||||||
r := &systemRouter{
|
r := &systemRouter{
|
||||||
backend: b,
|
backend: b,
|
||||||
}
|
}
|
||||||
|
|
||||||
r.routes = []router.Route{
|
r.routes = []router.Route{
|
||||||
local.NewOptionsRoute("/{anyroute:.*}", optionsHandler),
|
router.NewOptionsRoute("/{anyroute:.*}", optionsHandler),
|
||||||
local.NewGetRoute("/_ping", pingHandler),
|
router.NewGetRoute("/_ping", pingHandler),
|
||||||
local.NewGetRoute("/events", r.getEvents),
|
router.NewGetRoute("/events", r.getEvents),
|
||||||
local.NewGetRoute("/info", r.getInfo),
|
router.NewGetRoute("/info", r.getInfo),
|
||||||
local.NewGetRoute("/version", r.getVersion),
|
router.NewGetRoute("/version", r.getVersion),
|
||||||
local.NewPostRoute("/auth", r.postAuth),
|
router.NewPostRoute("/auth", r.postAuth),
|
||||||
}
|
}
|
||||||
|
|
||||||
return r
|
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 {
|
func (s *systemRouter) Routes() []router.Route {
|
||||||
return s.routes
|
return s.routes
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package volume
|
package volume
|
||||||
|
|
||||||
import (
|
import "github.com/docker/docker/api/server/router"
|
||||||
"github.com/docker/docker/api/server/router"
|
|
||||||
"github.com/docker/docker/api/server/router/local"
|
|
||||||
)
|
|
||||||
|
|
||||||
// volumeRouter is a router to talk with the volumes controller
|
// volumeRouter is a router to talk with the volumes controller
|
||||||
type volumeRouter struct {
|
type volumeRouter struct {
|
||||||
|
@ -11,7 +8,7 @@ type volumeRouter struct {
|
||||||
routes []router.Route
|
routes []router.Route
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRouter initializes a new volumeRouter
|
// NewRouter initializes a new volume router
|
||||||
func NewRouter(b Backend) router.Router {
|
func NewRouter(b Backend) router.Router {
|
||||||
r := &volumeRouter{
|
r := &volumeRouter{
|
||||||
backend: b,
|
backend: b,
|
||||||
|
@ -20,7 +17,7 @@ func NewRouter(b Backend) router.Router {
|
||||||
return r
|
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 {
|
func (r *volumeRouter) Routes() []router.Route {
|
||||||
return r.routes
|
return r.routes
|
||||||
}
|
}
|
||||||
|
@ -28,11 +25,11 @@ func (r *volumeRouter) Routes() []router.Route {
|
||||||
func (r *volumeRouter) initRoutes() {
|
func (r *volumeRouter) initRoutes() {
|
||||||
r.routes = []router.Route{
|
r.routes = []router.Route{
|
||||||
// GET
|
// GET
|
||||||
local.NewGetRoute("/volumes", r.getVolumesList),
|
router.NewGetRoute("/volumes", r.getVolumesList),
|
||||||
local.NewGetRoute("/volumes/{name:.*}", r.getVolumeByName),
|
router.NewGetRoute("/volumes/{name:.*}", r.getVolumeByName),
|
||||||
// POST
|
// POST
|
||||||
local.NewPostRoute("/volumes/create", r.postVolumesCreate),
|
router.NewPostRoute("/volumes/create", r.postVolumesCreate),
|
||||||
// DELETE
|
// DELETE
|
||||||
local.NewDeleteRoute("/volumes/{name:.*}", r.deleteVolumes),
|
router.NewDeleteRoute("/volumes/{name:.*}", r.deleteVolumes),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/docker/docker/api/server/router"
|
"github.com/docker/docker/api/server/router"
|
||||||
"github.com/docker/docker/api/server/router/build"
|
"github.com/docker/docker/api/server/router/build"
|
||||||
"github.com/docker/docker/api/server/router/container"
|
"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/network"
|
||||||
"github.com/docker/docker/api/server/router/system"
|
"github.com/docker/docker/api/server/router/system"
|
||||||
"github.com/docker/docker/api/server/router/volume"
|
"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.
|
// InitRouters initializes a list of routers for the server.
|
||||||
func (s *Server) InitRouters(d *daemon.Daemon) {
|
func (s *Server) InitRouters(d *daemon.Daemon) {
|
||||||
s.addRouter(container.NewRouter(d))
|
s.addRouter(container.NewRouter(d))
|
||||||
s.addRouter(local.NewRouter(d))
|
s.addRouter(image.NewRouter(d))
|
||||||
s.addRouter(network.NewRouter(d))
|
s.addRouter(network.NewRouter(d))
|
||||||
s.addRouter(system.NewRouter(d))
|
s.addRouter(system.NewRouter(d))
|
||||||
s.addRouter(volume.NewRouter(d))
|
s.addRouter(volume.NewRouter(d))
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Package backend includes types to send information to server backends.
|
||||||
|
// TODO(calavera): This package is pending of extraction to engine-api
|
||||||
|
// when the server package is clean of daemon dependencies.
|
||||||
|
package backend
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/docker/engine-api/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerWsAttachWithLogsConfig attach with websockets, since all
|
||||||
|
// stream data is delegated to the websocket to handle there.
|
||||||
|
type ContainerWsAttachWithLogsConfig struct {
|
||||||
|
InStream io.ReadCloser // Reader to attach to stdin of container
|
||||||
|
OutStream io.Writer // Writer to attach to stdout of container
|
||||||
|
ErrStream io.Writer // Writer to attach to stderr of container
|
||||||
|
Logs bool // If true return log output
|
||||||
|
Stream bool // If true return stream output
|
||||||
|
DetachKeys []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerLogsConfig holds configs for logging operations. Exists
|
||||||
|
// for users of the backend to to pass it a logging configuration.
|
||||||
|
type ContainerLogsConfig struct {
|
||||||
|
types.ContainerLogsOptions
|
||||||
|
OutStream io.Writer
|
||||||
|
Stop <-chan bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerStatsConfig holds information for configuring the runtime
|
||||||
|
// behavior of a backend.ContainerStats() call.
|
||||||
|
type ContainerStatsConfig struct {
|
||||||
|
Stream bool
|
||||||
|
OutStream io.Writer
|
||||||
|
Stop <-chan bool
|
||||||
|
Version string
|
||||||
|
}
|
|
@ -3,30 +3,18 @@ package daemon
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/docker/docker/api/types/backend"
|
||||||
"github.com/docker/docker/container"
|
"github.com/docker/docker/container"
|
||||||
"github.com/docker/docker/daemon/logger"
|
"github.com/docker/docker/daemon/logger"
|
||||||
derr "github.com/docker/docker/errors"
|
derr "github.com/docker/docker/errors"
|
||||||
"github.com/docker/docker/pkg/stdcopy"
|
"github.com/docker/docker/pkg/stdcopy"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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.
|
// 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 {
|
if c.Hijacker == nil {
|
||||||
return derr.ErrorCodeNoHijackConnection.WithArgs(prefixOrName)
|
return derr.ErrorCodeNoHijackConnection.WithArgs(prefixOrName)
|
||||||
}
|
}
|
||||||
|
@ -82,17 +70,8 @@ func (daemon *Daemon) ContainerAttachWithLogs(prefixOrName string, c *ContainerA
|
||||||
return nil
|
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
|
// 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)
|
container, err := daemon.GetContainer(prefixOrName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -102,7 +81,7 @@ func (daemon *Daemon) ContainerWsAttachWithLogs(prefixOrName string, c *Containe
|
||||||
|
|
||||||
// ContainerAttachOnBuild attaches streams to the container cID. If stream is true, it streams the output.
|
// ContainerAttachOnBuild attaches streams to the container cID. If stream is true, it streams the output.
|
||||||
func (daemon *Daemon) ContainerAttachOnBuild(cID string, stdin io.ReadCloser, stdout, stderr io.Writer, stream bool) error {
|
func (daemon *Daemon) ContainerAttachOnBuild(cID string, stdin io.ReadCloser, stdout, stderr io.Writer, stream bool) error {
|
||||||
return daemon.ContainerWsAttachWithLogs(cID, &ContainerWsAttachWithLogsConfig{
|
return daemon.ContainerWsAttachWithLogs(cID, &backend.ContainerWsAttachWithLogsConfig{
|
||||||
InStream: stdin,
|
InStream: stdin,
|
||||||
OutStream: stdout,
|
OutStream: stdout,
|
||||||
ErrStream: stderr,
|
ErrStream: stderr,
|
||||||
|
|
|
@ -43,24 +43,8 @@ func (daemon *Daemon) List() []*container.Container {
|
||||||
return daemon.containers.List()
|
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.
|
// 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 types.ContainerListOptions.
|
||||||
type listContext struct {
|
type listContext struct {
|
||||||
// idx is the container iteration index for this context
|
// idx is the container iteration index for this context
|
||||||
idx int
|
idx int
|
||||||
|
@ -80,17 +64,17 @@ type listContext struct {
|
||||||
// sinceFilter is a filter to stop the filtering when the iterator arrive to the given container
|
// sinceFilter is a filter to stop the filtering when the iterator arrive to the given container
|
||||||
// this is used for --filter=since= and --since=, the latter is deprecated.
|
// this is used for --filter=since= and --since=, the latter is deprecated.
|
||||||
sinceFilter *container.Container
|
sinceFilter *container.Container
|
||||||
// ContainersConfig is the filters set by the user
|
// ContainerListOptions is the filters set by the user
|
||||||
*ContainersConfig
|
*types.ContainerListOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
// Containers returns the list of containers to show given the user's filtering.
|
// 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 *types.ContainerListOptions) ([]*types.Container, error) {
|
||||||
return daemon.reduceContainers(config, daemon.transformContainer)
|
return daemon.reduceContainers(config, daemon.transformContainer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// reduceContainer parses the user filtering and generates the list of containers to return based on a reducer.
|
// reduceContainers parses the user's filtering options and generates the list of containers to return based on a reducer.
|
||||||
func (daemon *Daemon) reduceContainers(config *ContainersConfig, reducer containerReducer) ([]*types.Container, error) {
|
func (daemon *Daemon) reduceContainers(config *types.ContainerListOptions, reducer containerReducer) ([]*types.Container, error) {
|
||||||
containers := []*types.Container{}
|
containers := []*types.Container{}
|
||||||
|
|
||||||
ctx, err := daemon.foldFilter(config)
|
ctx, err := daemon.foldFilter(config)
|
||||||
|
@ -132,15 +116,12 @@ func (daemon *Daemon) reducePsContainer(container *container.Container, ctx *lis
|
||||||
return reducer(container, ctx)
|
return reducer(container, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// foldFilter generates the container filter based in the user's filtering options.
|
// foldFilter generates the container filter based on the user's filtering options.
|
||||||
func (daemon *Daemon) foldFilter(config *ContainersConfig) (*listContext, error) {
|
func (daemon *Daemon) foldFilter(config *types.ContainerListOptions) (*listContext, error) {
|
||||||
psFilters, err := filters.FromParam(config.Filters)
|
psFilters := config.Filter
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var filtExited []int
|
var filtExited []int
|
||||||
err = psFilters.WalkValues("exited", func(value string) error {
|
err := psFilters.WalkValues("exited", func(value string) error {
|
||||||
code, err := strconv.Atoi(value)
|
code, err := strconv.Atoi(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -216,14 +197,14 @@ func (daemon *Daemon) foldFilter(config *ContainersConfig) (*listContext, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &listContext{
|
return &listContext{
|
||||||
filters: psFilters,
|
filters: psFilters,
|
||||||
ancestorFilter: ancestorFilter,
|
ancestorFilter: ancestorFilter,
|
||||||
images: imagesFilter,
|
images: imagesFilter,
|
||||||
exitAllowed: filtExited,
|
exitAllowed: filtExited,
|
||||||
beforeFilter: beforeContFilter,
|
beforeFilter: beforeContFilter,
|
||||||
sinceFilter: sinceContFilter,
|
sinceFilter: sinceContFilter,
|
||||||
ContainersConfig: config,
|
ContainerListOptions: config,
|
||||||
names: daemon.nameIndex.GetAll(),
|
names: daemon.nameIndex.GetAll(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,39 +6,24 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/docker/docker/api/types/backend"
|
||||||
"github.com/docker/docker/container"
|
"github.com/docker/docker/container"
|
||||||
"github.com/docker/docker/daemon/logger"
|
"github.com/docker/docker/daemon/logger"
|
||||||
"github.com/docker/docker/daemon/logger/jsonfilelog"
|
"github.com/docker/docker/daemon/logger/jsonfilelog"
|
||||||
derr "github.com/docker/docker/errors"
|
derr "github.com/docker/docker/errors"
|
||||||
"github.com/docker/docker/pkg/stdcopy"
|
"github.com/docker/docker/pkg/stdcopy"
|
||||||
|
timetypes "github.com/docker/engine-api/types/time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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
|
// ContainerLogs hooks up a container's stdout and stderr streams
|
||||||
// configured with the given struct.
|
// 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)
|
container, err := daemon.GetContainer(containerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return derr.ErrorCodeNoSuchContainer.WithArgs(containerName)
|
return derr.ErrorCodeNoSuchContainer.WithArgs(containerName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(config.UseStdout || config.UseStderr) {
|
if !(config.ShowStdout || config.ShowStderr) {
|
||||||
return derr.ErrorCodeNeedStream
|
return derr.ErrorCodeNeedStream
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,8 +51,17 @@ func (daemon *Daemon) ContainerLogs(containerName string, config *ContainerLogsC
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Debug("logs: begin stream")
|
logrus.Debug("logs: begin stream")
|
||||||
|
|
||||||
|
var since time.Time
|
||||||
|
if config.Since != "" {
|
||||||
|
s, n, err := timetypes.ParseTimestamps(config.Since, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
since = time.Unix(s, n)
|
||||||
|
}
|
||||||
readConfig := logger.ReadConfig{
|
readConfig := logger.ReadConfig{
|
||||||
Since: config.Since,
|
Since: since,
|
||||||
Tail: tailLines,
|
Tail: tailLines,
|
||||||
Follow: follow,
|
Follow: follow,
|
||||||
}
|
}
|
||||||
|
@ -90,10 +84,10 @@ func (daemon *Daemon) ContainerLogs(containerName string, config *ContainerLogsC
|
||||||
if config.Timestamps {
|
if config.Timestamps {
|
||||||
logLine = append([]byte(msg.Timestamp.Format(logger.TimeFormat)+" "), logLine...)
|
logLine = append([]byte(msg.Timestamp.Format(logger.TimeFormat)+" "), logLine...)
|
||||||
}
|
}
|
||||||
if msg.Source == "stdout" && config.UseStdout {
|
if msg.Source == "stdout" && config.ShowStdout {
|
||||||
outStream.Write(logLine)
|
outStream.Write(logLine)
|
||||||
}
|
}
|
||||||
if msg.Source == "stderr" && config.UseStderr {
|
if msg.Source == "stderr" && config.ShowStderr {
|
||||||
errStream.Write(logLine)
|
errStream.Write(logLine)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package daemon
|
package daemon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -12,13 +11,6 @@ import (
|
||||||
"github.com/docker/libnetwork"
|
"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.
|
// NetworkControllerEnabled checks if the networking stack is enabled.
|
||||||
// This feature depends on OS primitives and it's disabled in systems like Windows.
|
// This feature depends on OS primitives and it's disabled in systems like Windows.
|
||||||
func (daemon *Daemon) NetworkControllerEnabled() bool {
|
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
|
// 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) {
|
func (daemon *Daemon) FindNetwork(idName string) (libnetwork.Network, error) {
|
||||||
// Find by Name
|
// Find by Name
|
||||||
n, err := daemon.GetNetwork(idName, NetworkByName)
|
n, err := daemon.GetNetworkByName(idName)
|
||||||
if _, ok := err.(libnetwork.ErrNoSuchNetwork); err != nil && !ok {
|
if err != nil && !isNoSuchNetworkError(err) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,38 +30,35 @@ func (daemon *Daemon) FindNetwork(idName string) (libnetwork.Network, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find by id
|
// Find by id
|
||||||
n, err = daemon.GetNetwork(idName, NetworkByID)
|
return daemon.GetNetworkByID(idName)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return n, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNetwork function returns a network for a given string that represents the network and
|
func isNoSuchNetworkError(err error) bool {
|
||||||
// a hint to indicate if the string is an Id or Name of the network
|
_, ok := err.(libnetwork.ErrNoSuchNetwork)
|
||||||
func (daemon *Daemon) GetNetwork(idName string, by int) (libnetwork.Network, error) {
|
return ok
|
||||||
c := daemon.netController
|
}
|
||||||
switch by {
|
|
||||||
case NetworkByID:
|
|
||||||
list := daemon.GetNetworksByID(idName)
|
|
||||||
|
|
||||||
if len(list) == 0 {
|
// GetNetworkByID function returns a network whose ID begins with the given prefix.
|
||||||
return nil, libnetwork.ErrNoSuchNetwork(idName)
|
// 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 {
|
if len(list) == 0 {
|
||||||
return nil, libnetwork.ErrInvalidID(idName)
|
return nil, libnetwork.ErrNoSuchNetwork(partialID)
|
||||||
}
|
|
||||||
|
|
||||||
return list[0], nil
|
|
||||||
case NetworkByName:
|
|
||||||
if idName == "" {
|
|
||||||
idName = c.Config().Daemon.DefaultNetwork
|
|
||||||
}
|
|
||||||
return c.NetworkByName(idName)
|
|
||||||
}
|
}
|
||||||
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
|
// GetNetworksByID returns a list of networks whose ID partially matches zero or more networks
|
||||||
|
|
|
@ -3,30 +3,23 @@ package daemon
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/docker/docker/api/types/backend"
|
||||||
"github.com/docker/docker/daemon/execdriver"
|
"github.com/docker/docker/daemon/execdriver"
|
||||||
"github.com/docker/docker/pkg/version"
|
"github.com/docker/docker/pkg/version"
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
"github.com/docker/engine-api/types/versions/v1p20"
|
"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
|
// ContainerStats writes information about the container to the stream
|
||||||
// given in the config object.
|
// 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" {
|
if runtime.GOOS == "windows" {
|
||||||
return errors.New("Windows does not support stats")
|
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)
|
container, err := daemon.GetContainer(prefixOrName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -72,7 +65,7 @@ func (daemon *Daemon) ContainerStats(prefixOrName string, config *ContainerStats
|
||||||
|
|
||||||
var statsJSON interface{}
|
var statsJSON interface{}
|
||||||
statsJSONPost120 := getStatJSON(v)
|
statsJSONPost120 := getStatJSON(v)
|
||||||
if config.Version.LessThan("1.21") {
|
if apiVersion.LessThan("1.21") {
|
||||||
var (
|
var (
|
||||||
rxBytes uint64
|
rxBytes uint64
|
||||||
rxPackets uint64
|
rxPackets uint64
|
||||||
|
|
Loading…
Reference in New Issue