Browse code

Add a DOCKER_API_VERSION env var

Closes: #11486

Just for @ahmetalpbalkan :-)

Fixed some comment formatting too while in there.

Signed-off-by: Doug Davis <dug@us.ibm.com>

Doug Davis authored on 2015/09/01 06:45:27
Showing 9 changed files
... ...
@@ -103,7 +103,12 @@ func NewDockerCli(in io.ReadCloser, out, err io.Writer, clientFlags *cli.ClientF
103 103
 		}
104 104
 		customHeaders["User-Agent"] = "Docker-Client/" + dockerversion.Version + " (" + runtime.GOOS + ")"
105 105
 
106
-		client, err := lib.NewClient(host, string(api.Version), clientFlags.Common.TLSOptions, customHeaders)
106
+		verStr := string(api.DefaultVersion)
107
+		if tmpStr := os.Getenv("DOCKER_API_VERSION"); tmpStr != "" {
108
+			verStr = tmpStr
109
+		}
110
+
111
+		client, err := lib.NewClient(host, verStr, clientFlags.Common.TLSOptions, customHeaders)
107 112
 		if err != nil {
108 113
 			return err
109 114
 		}
... ...
@@ -17,6 +17,7 @@ import (
17 17
 
18 18
 // apiClient is an interface that clients that talk with a docker server must implement.
19 19
 type apiClient interface {
20
+	ClientVersion() string
20 21
 	ContainerAttach(options types.ContainerAttachOptions) (types.HijackedResponse, error)
21 22
 	ContainerCommit(options types.ContainerCommitOptions) (types.ContainerCommitResponse, error)
22 23
 	ContainerCreate(config *runconfig.ContainerConfigWrapper, containerName string) (types.ContainerCreateResponse, error)
... ...
@@ -96,3 +96,10 @@ func (cli *Client) getAPIPath(p string, query url.Values) string {
96 96
 	}
97 97
 	return apiPath
98 98
 }
99
+
100
+// ClientVersion returns the version string associated with this
101
+// instance of the Client. Note that this value can be changed
102
+// via the DOCKER_API_VERSION env var.
103
+func (cli *Client) ClientVersion() string {
104
+	return cli.version
105
+}
... ...
@@ -5,11 +5,11 @@ import (
5 5
 	"text/template"
6 6
 	"time"
7 7
 
8
-	"github.com/docker/docker/api"
9 8
 	"github.com/docker/docker/api/types"
10 9
 	Cli "github.com/docker/docker/cli"
11 10
 	"github.com/docker/docker/dockerversion"
12 11
 	flag "github.com/docker/docker/pkg/mflag"
12
+	"github.com/docker/docker/pkg/version"
13 13
 	"github.com/docker/docker/utils"
14 14
 )
15 15
 
... ...
@@ -57,7 +57,7 @@ func (cli *DockerCli) CmdVersion(args ...string) (err error) {
57 57
 	vd := types.VersionResponse{
58 58
 		Client: &types.Version{
59 59
 			Version:      dockerversion.Version,
60
-			APIVersion:   api.Version,
60
+			APIVersion:   version.Version(cli.client.ClientVersion()),
61 61
 			GoVersion:    runtime.Version(),
62 62
 			GitCommit:    dockerversion.GitCommit,
63 63
 			BuildTime:    dockerversion.BuildTime,
... ...
@@ -18,7 +18,7 @@ import (
18 18
 // Common constants for daemon and client.
19 19
 const (
20 20
 	// Version of Current REST API
21
-	Version version.Version = "1.22"
21
+	DefaultVersion version.Version = "1.22"
22 22
 
23 23
 	// MinVersion represents Minimum REST API version supported
24 24
 	MinVersion version.Version = "1.12"
... ...
@@ -121,14 +121,14 @@ func versionMiddleware(handler httputils.APIFunc) httputils.APIFunc {
121 121
 	return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
122 122
 		apiVersion := version.Version(vars["version"])
123 123
 		if apiVersion == "" {
124
-			apiVersion = api.Version
124
+			apiVersion = api.DefaultVersion
125 125
 		}
126 126
 
127
-		if apiVersion.GreaterThan(api.Version) {
128
-			return errors.ErrorCodeNewerClientVersion.WithArgs(apiVersion, api.Version)
127
+		if apiVersion.GreaterThan(api.DefaultVersion) {
128
+			return errors.ErrorCodeNewerClientVersion.WithArgs(apiVersion, api.DefaultVersion)
129 129
 		}
130 130
 		if apiVersion.LessThan(api.MinVersion) {
131
-			return errors.ErrorCodeOldClientVersion.WithArgs(apiVersion, api.Version)
131
+			return errors.ErrorCodeOldClientVersion.WithArgs(apiVersion, api.DefaultVersion)
132 132
 		}
133 133
 
134 134
 		w.Header().Set("Server", "Docker/"+dockerversion.Version+" ("+runtime.GOOS+")")
... ...
@@ -38,7 +38,7 @@ func (s *systemRouter) getInfo(ctx context.Context, w http.ResponseWriter, r *ht
38 38
 
39 39
 func (s *systemRouter) getVersion(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
40 40
 	info := s.backend.SystemVersion()
41
-	info.APIVersion = api.Version
41
+	info.APIVersion = api.DefaultVersion
42 42
 
43 43
 	return httputils.WriteJSON(w, http.StatusOK, info)
44 44
 }
... ...
@@ -38,6 +38,7 @@ the [installation](../../installation/index.md) instructions for your operating
38 38
 For easy reference, the following list of environment variables are supported
39 39
 by the `docker` command line:
40 40
 
41
+* `DOCKER_API_VERSION` The API version to use (e.g. `1.19`)
41 42
 * `DOCKER_CONFIG` The location of your client configuration files.
42 43
 * `DOCKER_CERT_PATH` The location of your authentication keys.
43 44
 * `DOCKER_DRIVER` The graph driver to use.
... ...
@@ -2,7 +2,10 @@ package main
2 2
 
3 3
 import (
4 4
 	"net/http"
5
+	"net/http/httptest"
5 6
 	"net/http/httputil"
7
+	"os"
8
+	"os/exec"
6 9
 	"strconv"
7 10
 	"strings"
8 11
 	"time"
... ...
@@ -46,7 +49,7 @@ func (s *DockerSuite) TestApiVersionStatusCode(c *check.C) {
46 46
 }
47 47
 
48 48
 func (s *DockerSuite) TestApiClientVersionNewerThanServer(c *check.C) {
49
-	v := strings.Split(string(api.Version), ".")
49
+	v := strings.Split(string(api.DefaultVersion), ".")
50 50
 	vMinInt, err := strconv.Atoi(v[1])
51 51
 	c.Assert(err, checker.IsNil)
52 52
 	vMinInt++
... ...
@@ -72,3 +75,25 @@ func (s *DockerSuite) TestApiClientVersionOldNotSupported(c *check.C) {
72 72
 	c.Assert(status, checker.Equals, http.StatusBadRequest)
73 73
 	c.Assert(len(string(body)), checker.Not(check.Equals), 0) // Expected not empty body
74 74
 }
75
+
76
+func (s *DockerSuite) TestApiDockerApiVersion(c *check.C) {
77
+	var svrVersion string
78
+
79
+	server := httptest.NewServer(http.HandlerFunc(
80
+		func(w http.ResponseWriter, r *http.Request) {
81
+			url := r.URL.Path
82
+			svrVersion = url
83
+		}))
84
+	defer server.Close()
85
+
86
+	// Test using the env var first
87
+	cmd := exec.Command(dockerBinary, "-H="+server.URL[7:], "version")
88
+	cmd.Env = append([]string{"DOCKER_API_VERSION=xxx"}, os.Environ()...)
89
+	out, _, _ := runCommandWithOutput(cmd)
90
+
91
+	c.Assert(svrVersion, check.Equals, "/vxxx/version")
92
+
93
+	if !strings.Contains(out, "API version:  xxx") {
94
+		c.Fatalf("Out didn't have 'xxx' for the API version, had:\n%s", out)
95
+	}
96
+}