1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #15953 from duglin/DaemonContext

Add a "context" to the api/server/* code
This commit is contained in:
David Calavera 2015-09-09 17:28:38 -07:00
commit 6efe45990d
11 changed files with 190 additions and 67 deletions

View file

@ -6,10 +6,10 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/cliconfig"
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/context"
)
func (s *Server) postAuth(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postAuth(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var config *cliconfig.AuthConfig
err := json.NewDecoder(r.Body).Decode(&config)
r.Body.Close()

View file

@ -12,14 +12,14 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types"
"github.com/docker/docker/context"
"github.com/docker/docker/daemon"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/runconfig"
)
func (s *Server) getContainersJSON(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getContainersJSON(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -48,7 +48,7 @@ func (s *Server) getContainersJSON(version version.Version, w http.ResponseWrite
return writeJSON(w, http.StatusOK, containers)
}
func (s *Server) getContainersStats(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getContainersStats(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -89,7 +89,7 @@ func (s *Server) getContainersStats(version version.Version, w http.ResponseWrit
return s.daemon.ContainerStats(container, config)
}
func (s *Server) getContainersLogs(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getContainersLogs(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -146,7 +146,7 @@ func (s *Server) getContainersLogs(version version.Version, w http.ResponseWrite
return nil
}
func (s *Server) getContainersExport(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getContainersExport(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -154,7 +154,7 @@ func (s *Server) getContainersExport(version version.Version, w http.ResponseWri
return s.daemon.ContainerExport(vars["name"], w)
}
func (s *Server) postContainersStart(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainersStart(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -190,7 +190,7 @@ func (s *Server) postContainersStart(version version.Version, w http.ResponseWri
return nil
}
func (s *Server) postContainersStop(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainersStop(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -212,7 +212,7 @@ func (s *Server) postContainersStop(version version.Version, w http.ResponseWrit
return nil
}
func (s *Server) postContainersKill(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainersKill(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -250,6 +250,7 @@ func (s *Server) postContainersKill(version version.Version, w http.ResponseWrit
// Return error that's not caused because the container is stopped.
// Return error if the container is not running and the api is >= 1.20
// to keep backwards compatibility.
version := ctx.Version()
if version.GreaterThanOrEqualTo("1.20") || !isStopped {
return fmt.Errorf("Cannot kill container %s: %v", name, err)
}
@ -259,7 +260,7 @@ func (s *Server) postContainersKill(version version.Version, w http.ResponseWrit
return nil
}
func (s *Server) postContainersRestart(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainersRestart(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -278,7 +279,7 @@ func (s *Server) postContainersRestart(version version.Version, w http.ResponseW
return nil
}
func (s *Server) postContainersPause(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainersPause(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -295,7 +296,7 @@ func (s *Server) postContainersPause(version version.Version, w http.ResponseWri
return nil
}
func (s *Server) postContainersUnpause(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainersUnpause(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -312,7 +313,7 @@ func (s *Server) postContainersUnpause(version version.Version, w http.ResponseW
return nil
}
func (s *Server) postContainersWait(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainersWait(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -327,7 +328,7 @@ func (s *Server) postContainersWait(version version.Version, w http.ResponseWrit
})
}
func (s *Server) getContainersChanges(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getContainersChanges(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -340,7 +341,7 @@ func (s *Server) getContainersChanges(version version.Version, w http.ResponseWr
return writeJSON(w, http.StatusOK, changes)
}
func (s *Server) getContainersTop(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getContainersTop(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -357,7 +358,7 @@ func (s *Server) getContainersTop(version version.Version, w http.ResponseWriter
return writeJSON(w, http.StatusOK, procList)
}
func (s *Server) postContainerRename(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainerRename(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -374,7 +375,7 @@ func (s *Server) postContainerRename(version version.Version, w http.ResponseWri
return nil
}
func (s *Server) postContainersCreate(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainersCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -390,6 +391,7 @@ func (s *Server) postContainersCreate(version version.Version, w http.ResponseWr
if err != nil {
return err
}
version := ctx.Version()
adjustCPUShares := version.LessThan("1.19")
container, warnings, err := s.daemon.ContainerCreate(name, config, hostConfig, adjustCPUShares)
@ -403,7 +405,7 @@ func (s *Server) postContainersCreate(version version.Version, w http.ResponseWr
})
}
func (s *Server) deleteContainers(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) deleteContainers(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -431,7 +433,7 @@ func (s *Server) deleteContainers(version version.Version, w http.ResponseWriter
return nil
}
func (s *Server) postContainersResize(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainersResize(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -451,7 +453,7 @@ func (s *Server) postContainersResize(version version.Version, w http.ResponseWr
return s.daemon.ContainerResize(vars["name"], height, width)
}
func (s *Server) postContainersAttach(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainersAttach(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -493,7 +495,7 @@ func (s *Server) postContainersAttach(version version.Version, w http.ResponseWr
return nil
}
func (s *Server) wsContainersAttach(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) wsContainersAttach(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}

View file

@ -10,11 +10,11 @@ import (
"strings"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/context"
)
// postContainersCopy is deprecated in favor of getContainersArchive.
func (s *Server) postContainersCopy(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainersCopy(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -68,7 +68,7 @@ func setContainerPathStatHeader(stat *types.ContainerPathStat, header http.Heade
return nil
}
func (s *Server) headContainersArchive(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) headContainersArchive(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
v, err := archiveFormValues(r, vars)
if err != nil {
return err
@ -82,7 +82,7 @@ func (s *Server) headContainersArchive(version version.Version, w http.ResponseW
return setContainerPathStatHeader(stat, w.Header())
}
func (s *Server) getContainersArchive(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getContainersArchive(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
v, err := archiveFormValues(r, vars)
if err != nil {
return err
@ -104,7 +104,7 @@ func (s *Server) getContainersArchive(version version.Version, w http.ResponseWr
return err
}
func (s *Server) putContainersArchive(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) putContainersArchive(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
v, err := archiveFormValues(r, vars)
if err != nil {
return err

View file

@ -12,15 +12,15 @@ import (
"github.com/docker/docker/api"
"github.com/docker/docker/api/types"
"github.com/docker/docker/autogen/dockerversion"
"github.com/docker/docker/context"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/pkg/parsers/filters"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/utils"
)
func (s *Server) getVersion(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getVersion(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
v := &types.Version{
Version: dockerversion.VERSION,
APIVersion: api.Version,
@ -31,6 +31,8 @@ func (s *Server) getVersion(version version.Version, w http.ResponseWriter, r *h
BuildTime: dockerversion.BUILDTIME,
}
version := ctx.Version()
if version.GreaterThanOrEqualTo("1.19") {
v.Experimental = utils.ExperimentalBuild()
}
@ -42,7 +44,7 @@ func (s *Server) getVersion(version version.Version, w http.ResponseWriter, r *h
return writeJSON(w, http.StatusOK, v)
}
func (s *Server) getInfo(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getInfo(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
info, err := s.daemon.SystemInfo()
if err != nil {
return err
@ -51,7 +53,7 @@ func (s *Server) getInfo(version version.Version, w http.ResponseWriter, r *http
return writeJSON(w, http.StatusOK, info)
}
func (s *Server) getEvents(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getEvents(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}

View file

@ -9,12 +9,12 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types"
"github.com/docker/docker/context"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/runconfig"
)
func (s *Server) getExecByID(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getExecByID(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter 'id'")
}
@ -27,7 +27,7 @@ func (s *Server) getExecByID(version version.Version, w http.ResponseWriter, r *
return writeJSON(w, http.StatusOK, eConfig)
}
func (s *Server) postContainerExecCreate(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainerExecCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -59,7 +59,7 @@ func (s *Server) postContainerExecCreate(version version.Version, w http.Respons
}
// TODO(vishh): Refactor the code to avoid having to specify stream config as part of both create and start.
func (s *Server) postContainerExecStart(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainerExecStart(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -106,7 +106,7 @@ func (s *Server) postContainerExecStart(version version.Version, w http.Response
return nil
}
func (s *Server) postContainerExecResize(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postContainerExecResize(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}

View file

@ -12,17 +12,17 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/builder"
"github.com/docker/docker/cliconfig"
"github.com/docker/docker/context"
"github.com/docker/docker/graph"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/docker/pkg/ulimit"
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/utils"
)
func (s *Server) postCommit(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postCommit(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -34,6 +34,7 @@ func (s *Server) postCommit(version version.Version, w http.ResponseWriter, r *h
cname := r.Form.Get("container")
pause := boolValue(r, "pause")
version := ctx.Version()
if r.FormValue("pause") == "" && version.GreaterThanOrEqualTo("1.13") {
pause = true
}
@ -64,7 +65,7 @@ func (s *Server) postCommit(version version.Version, w http.ResponseWriter, r *h
}
// Creates an image from Pull or from Import
func (s *Server) postImagesCreate(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postImagesCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -140,7 +141,7 @@ func (s *Server) postImagesCreate(version version.Version, w http.ResponseWriter
return nil
}
func (s *Server) postImagesPush(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postImagesPush(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -192,7 +193,7 @@ func (s *Server) postImagesPush(version version.Version, w http.ResponseWriter,
return nil
}
func (s *Server) getImagesGet(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getImagesGet(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -220,11 +221,11 @@ func (s *Server) getImagesGet(version version.Version, w http.ResponseWriter, r
return nil
}
func (s *Server) postImagesLoad(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postImagesLoad(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
return s.daemon.Repositories().Load(r.Body, w)
}
func (s *Server) deleteImages(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) deleteImages(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -249,7 +250,7 @@ func (s *Server) deleteImages(version version.Version, w http.ResponseWriter, r
return writeJSON(w, http.StatusOK, list)
}
func (s *Server) getImagesByName(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getImagesByName(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -262,7 +263,7 @@ func (s *Server) getImagesByName(version version.Version, w http.ResponseWriter,
return writeJSON(w, http.StatusOK, imageInspect)
}
func (s *Server) postBuild(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postBuild(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var (
authConfigs = map[string]cliconfig.AuthConfig{}
authConfigsEncoded = r.Header.Get("X-Registry-Config")
@ -280,6 +281,7 @@ func (s *Server) postBuild(version version.Version, w http.ResponseWriter, r *ht
w.Header().Set("Content-Type", "application/json")
version := ctx.Version()
if boolValue(r, "forcerm") && version.GreaterThanOrEqualTo("1.12") {
buildConfig.Remove = true
} else if r.FormValue("rm") == "" && version.GreaterThanOrEqualTo("1.12") {
@ -346,7 +348,7 @@ func (s *Server) postBuild(version version.Version, w http.ResponseWriter, r *ht
return nil
}
func (s *Server) getImagesJSON(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getImagesJSON(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -360,7 +362,7 @@ func (s *Server) getImagesJSON(version version.Version, w http.ResponseWriter, r
return writeJSON(w, http.StatusOK, images)
}
func (s *Server) getImagesHistory(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getImagesHistory(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -374,7 +376,7 @@ func (s *Server) getImagesHistory(version version.Version, w http.ResponseWriter
return writeJSON(w, http.StatusOK, history)
}
func (s *Server) postImagesTag(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postImagesTag(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -394,7 +396,7 @@ func (s *Server) postImagesTag(version version.Version, w http.ResponseWriter, r
return nil
}
func (s *Server) getImagesSearch(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getImagesSearch(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}

View file

@ -4,11 +4,11 @@ import (
"fmt"
"net/http"
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/context"
)
// getContainersByName inspects containers configuration and serializes it as json.
func (s *Server) getContainersByName(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getContainersByName(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
}
@ -16,6 +16,8 @@ func (s *Server) getContainersByName(version version.Version, w http.ResponseWri
var json interface{}
var err error
version := ctx.Version()
switch {
case version.LessThan("1.20"):
json, err = s.daemon.ContainerInspectPre120(vars["name"])

View file

@ -16,8 +16,10 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api"
"github.com/docker/docker/autogen/dockerversion"
"github.com/docker/docker/context"
"github.com/docker/docker/daemon"
"github.com/docker/docker/pkg/sockets"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/docker/pkg/version"
)
@ -122,7 +124,7 @@ func (s *HTTPServer) Close() error {
// HTTPAPIFunc is an adapter to allow the use of ordinary functions as Docker API endpoints.
// Any function that has the appropriate signature can be register as a API endpoint (e.g. getVersion).
type HTTPAPIFunc func(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error
type HTTPAPIFunc func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error
func hijackServer(w http.ResponseWriter) (io.ReadCloser, io.Writer, error) {
conn, _, err := w.(http.Hijacker).Hijack()
@ -219,7 +221,7 @@ func writeJSON(w http.ResponseWriter, code int, v interface{}) error {
return json.NewEncoder(w).Encode(v)
}
func (s *Server) optionsHandler(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) optionsHandler(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
w.WriteHeader(http.StatusOK)
return nil
}
@ -230,7 +232,7 @@ func writeCorsHeaders(w http.ResponseWriter, r *http.Request, corsHeaders string
w.Header().Add("Access-Control-Allow-Methods", "HEAD, GET, POST, DELETE, PUT, OPTIONS")
}
func (s *Server) ping(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) ping(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
_, err := w.Write([]byte{'O', 'K'})
return err
}
@ -250,6 +252,24 @@ func (s *Server) initTCPSocket(addr string) (l net.Listener, err error) {
func makeHTTPHandler(logging bool, localMethod string, localRoute string, handlerFunc HTTPAPIFunc, corsHeaders string, dockerVersion version.Version) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Define the context that we'll pass around to share info
// like the docker-request-id.
//
// The 'context' will be used for global data that should
// apply to all requests. Data that is specific to the
// immediate function being called should still be passed
// as 'args' on the function call.
reqID := stringid.TruncateID(stringid.GenerateNonCryptoID())
apiVersion := version.Version(mux.Vars(r)["version"])
if apiVersion == "" {
apiVersion = api.Version
}
ctx := context.Background()
ctx = context.WithValue(ctx, context.RequestID, reqID)
ctx = context.WithValue(ctx, context.APIVersion, apiVersion)
// log the request
logrus.Debugf("Calling %s %s", localMethod, localRoute)
@ -270,26 +290,22 @@ func makeHTTPHandler(logging bool, localMethod string, localRoute string, handle
logrus.Debugf("Warning: client and server don't have the same version (client: %s, server: %s)", userAgent[1], dockerVersion)
}
}
version := version.Version(mux.Vars(r)["version"])
if version == "" {
version = api.Version
}
if corsHeaders != "" {
writeCorsHeaders(w, r, corsHeaders)
}
if version.GreaterThan(api.Version) {
http.Error(w, fmt.Errorf("client is newer than server (client API version: %s, server API version: %s)", version, api.Version).Error(), http.StatusBadRequest)
if apiVersion.GreaterThan(api.Version) {
http.Error(w, fmt.Errorf("client is newer than server (client API version: %s, server API version: %s)", apiVersion, api.Version).Error(), http.StatusBadRequest)
return
}
if version.LessThan(api.MinVersion) {
if apiVersion.LessThan(api.MinVersion) {
http.Error(w, fmt.Errorf("client is too old, minimum supported API version is %s, please upgrade your client to a newer version", api.MinVersion).Error(), http.StatusBadRequest)
return
}
w.Header().Set("Server", "Docker/"+dockerversion.VERSION+" ("+runtime.GOOS+")")
if err := handlerFunc(version, w, r, mux.Vars(r)); err != nil {
if err := handlerFunc(ctx, w, r, mux.Vars(r)); err != nil {
logrus.Errorf("Handler for %s %s returned error: %s", localMethod, localRoute, err)
httpError(w, err)
}

View file

@ -5,10 +5,10 @@ import (
"net/http"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/version"
"github.com/docker/docker/context"
)
func (s *Server) getVolumesList(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getVolumesList(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -20,7 +20,7 @@ func (s *Server) getVolumesList(version version.Version, w http.ResponseWriter,
return writeJSON(w, http.StatusOK, &types.VolumesListResponse{Volumes: volumes})
}
func (s *Server) getVolumeByName(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) getVolumeByName(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -32,7 +32,7 @@ func (s *Server) getVolumeByName(version version.Version, w http.ResponseWriter,
return writeJSON(w, http.StatusOK, v)
}
func (s *Server) postVolumesCreate(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) postVolumesCreate(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}
@ -53,7 +53,7 @@ func (s *Server) postVolumesCreate(version version.Version, w http.ResponseWrite
return writeJSON(w, http.StatusCreated, volume)
}
func (s *Server) deleteVolumes(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
func (s *Server) deleteVolumes(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if err := parseForm(r); err != nil {
return err
}

64
context/context.go Normal file
View file

@ -0,0 +1,64 @@
package context
import (
"golang.org/x/net/context"
"github.com/docker/docker/pkg/version"
)
const (
// RequestID is the unique ID for each http request
RequestID = "request-id"
// APIVersion is the client's requested API version
APIVersion = "api-version"
)
// Context is just our own wrapper for the golang 'Context' - mainly
// so we can add our over version of the funcs.
type Context struct {
context.Context
}
// Background creates a new Context based on golang's default one.
func Background() Context {
return Context{context.Background()}
}
// WithValue will return a Context that has this new key/value pair
// associated with it. Just uses the golang version but then wraps it.
func WithValue(ctx Context, key, value interface{}) Context {
return Context{context.WithValue(ctx, key, value)}
}
// RequestID is a utility func to make it easier to get the
// request ID associated with this Context/request.
func (ctx Context) RequestID() string {
val := ctx.Value(RequestID)
if val == nil {
return ""
}
id, ok := val.(string)
if !ok {
// Ideally we shouldn't panic but we also should never get here
panic("Context RequestID isn't a string")
}
return id
}
// Version is a utility func to make it easier to get the
// API version string associated with this Context/request.
func (ctx Context) Version() version.Version {
val := ctx.Value(APIVersion)
if val == nil {
return version.Version("")
}
ver, ok := val.(version.Version)
if !ok {
// Ideally we shouldn't panic but we also should never get here
panic("Context APIVersion isn't a version.Version")
}
return ver
}

35
context/context_test.go Normal file
View file

@ -0,0 +1,35 @@
package context
import (
"testing"
"github.com/docker/docker/pkg/version"
)
func TestContext(t *testing.T) {
ctx := Background()
// First make sure getting non-existent values doesn't break
if id := ctx.RequestID(); id != "" {
t.Fatalf("RequestID() should have been '', was: %q", id)
}
if ver := ctx.Version(); ver != "" {
t.Fatalf("Version() should have been '', was: %q", ver)
}
// Test basic set/get
ctx = WithValue(ctx, RequestID, "123")
if ctx.RequestID() != "123" {
t.Fatalf("RequestID() should have been '123'")
}
// Now make sure after a 2nd set we can still get both
ctx = WithValue(ctx, APIVersion, version.Version("x.y"))
if id := ctx.RequestID(); id != "123" {
t.Fatalf("RequestID() should have been '123', was %q", id)
}
if ver := ctx.Version(); ver != "x.y" {
t.Fatalf("Version() should have been 'x.y', was %q", ver)
}
}