diff --git a/api/server/auth.go b/api/server/auth.go index 6562b97ed0..0373a9d2e1 100644 --- a/api/server/auth.go +++ b/api/server/auth.go @@ -4,10 +4,9 @@ import ( "encoding/json" "net/http" - "golang.org/x/net/context" - "github.com/docker/docker/api/types" "github.com/docker/docker/cliconfig" + "github.com/docker/docker/context" ) func (s *Server) postAuth(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { diff --git a/api/server/container.go b/api/server/container.go index 36d86472f1..3af7972674 100644 --- a/api/server/container.go +++ b/api/server/container.go @@ -8,15 +8,14 @@ import ( "strings" "time" - "golang.org/x/net/context" "golang.org/x/net/websocket" "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" ) @@ -251,7 +250,7 @@ func (s *Server) postContainersKill(ctx context.Context, w http.ResponseWriter, // 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.Value("api-version").(version.Version) + version := ctx.Version() if version.GreaterThanOrEqualTo("1.20") || !isStopped { return fmt.Errorf("Cannot kill container %s: %v", name, err) } @@ -392,7 +391,7 @@ func (s *Server) postContainersCreate(ctx context.Context, w http.ResponseWriter if err != nil { return err } - version, _ := ctx.Value("api-version").(version.Version) + version := ctx.Version() adjustCPUShares := version.LessThan("1.19") container, warnings, err := s.daemon.ContainerCreate(name, config, hostConfig, adjustCPUShares) diff --git a/api/server/copy.go b/api/server/copy.go index 86c4a4fabf..b3d8ed320e 100644 --- a/api/server/copy.go +++ b/api/server/copy.go @@ -9,9 +9,8 @@ import ( "os" "strings" - "golang.org/x/net/context" - "github.com/docker/docker/api/types" + "github.com/docker/docker/context" ) // postContainersCopy is deprecated in favor of getContainersArchive. diff --git a/api/server/daemon.go b/api/server/daemon.go index c70b8fe646..df3cba9704 100644 --- a/api/server/daemon.go +++ b/api/server/daemon.go @@ -8,17 +8,15 @@ import ( "strings" "time" - "golang.org/x/net/context" - "github.com/Sirupsen/logrus" "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" ) @@ -33,7 +31,7 @@ func (s *Server) getVersion(ctx context.Context, w http.ResponseWriter, r *http. BuildTime: dockerversion.BUILDTIME, } - version, _ := ctx.Value("api-version").(version.Version) + version := ctx.Version() if version.GreaterThanOrEqualTo("1.19") { v.Experimental = utils.ExperimentalBuild() diff --git a/api/server/exec.go b/api/server/exec.go index 83540b6253..46d46c58b7 100644 --- a/api/server/exec.go +++ b/api/server/exec.go @@ -7,10 +7,9 @@ import ( "net/http" "strconv" - "golang.org/x/net/context" - "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/runconfig" ) diff --git a/api/server/image.go b/api/server/image.go index 5922ba4f7f..6ca18be69e 100644 --- a/api/server/image.go +++ b/api/server/image.go @@ -8,18 +8,16 @@ import ( "net/http" "strings" - "golang.org/x/net/context" - "github.com/Sirupsen/logrus" "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" ) @@ -36,7 +34,7 @@ func (s *Server) postCommit(ctx context.Context, w http.ResponseWriter, r *http. cname := r.Form.Get("container") pause := boolValue(r, "pause") - version, _ := ctx.Value("api-version").(version.Version) + version := ctx.Version() if r.FormValue("pause") == "" && version.GreaterThanOrEqualTo("1.13") { pause = true } @@ -283,7 +281,7 @@ func (s *Server) postBuild(ctx context.Context, w http.ResponseWriter, r *http.R w.Header().Set("Content-Type", "application/json") - version, _ := ctx.Value("api-version").(version.Version) + version := ctx.Version() if boolValue(r, "forcerm") && version.GreaterThanOrEqualTo("1.12") { buildConfig.Remove = true } else if r.FormValue("rm") == "" && version.GreaterThanOrEqualTo("1.12") { diff --git a/api/server/inspect.go b/api/server/inspect.go index d681a2a342..782ae4865c 100644 --- a/api/server/inspect.go +++ b/api/server/inspect.go @@ -4,9 +4,7 @@ import ( "fmt" "net/http" - "golang.org/x/net/context" - - "github.com/docker/docker/pkg/version" + "github.com/docker/docker/context" ) // getContainersByName inspects containers configuration and serializes it as json. @@ -18,7 +16,7 @@ func (s *Server) getContainersByName(ctx context.Context, w http.ResponseWriter, var json interface{} var err error - version, _ := ctx.Value("api-version").(version.Version) + version := ctx.Version() switch { case version.LessThan("1.20"): diff --git a/api/server/server.go b/api/server/server.go index fa6748f4b1..f7d85138a7 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -12,11 +12,11 @@ import ( "strings" "github.com/gorilla/mux" - "golang.org/x/net/context" "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" @@ -261,14 +261,14 @@ func makeHTTPHandler(logging bool, localMethod string, localRoute string, handle // as 'args' on the function call. reqID := stringid.TruncateID(stringid.GenerateNonCryptoID()) - api_version := version.Version(mux.Vars(r)["version"]) - if api_version == "" { - api_version = api.Version + apiVersion := version.Version(mux.Vars(r)["version"]) + if apiVersion == "" { + apiVersion = api.Version } ctx := context.Background() - ctx = context.WithValue(ctx, "docker-request-id", reqID) - ctx = context.WithValue(ctx, "api-version", api_version) + ctx = context.WithValue(ctx, context.RequestID, reqID) + ctx = context.WithValue(ctx, context.APIVersion, apiVersion) // log the request logrus.Debugf("Calling %s %s", localMethod, localRoute) @@ -294,11 +294,11 @@ func makeHTTPHandler(logging bool, localMethod string, localRoute string, handle writeCorsHeaders(w, r, corsHeaders) } - if api_version.GreaterThan(api.Version) { - http.Error(w, fmt.Errorf("client is newer than server (client API version: %s, server API version: %s)", api_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 api_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 } diff --git a/api/server/volume.go b/api/server/volume.go index c92f0bdaab..cec3b820c4 100644 --- a/api/server/volume.go +++ b/api/server/volume.go @@ -4,9 +4,8 @@ import ( "encoding/json" "net/http" - "golang.org/x/net/context" - "github.com/docker/docker/api/types" + "github.com/docker/docker/context" ) func (s *Server) getVolumesList(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { diff --git a/context/context.go b/context/context.go new file mode 100644 index 0000000000..3532507c3d --- /dev/null +++ b/context/context.go @@ -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 +} diff --git a/context/context_test.go b/context/context_test.go new file mode 100644 index 0000000000..e1ec47435b --- /dev/null +++ b/context/context_test.go @@ -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) + } +}