Signed-off-by: Antonio Murdaca <runcom@linux.com>
| ... | ... |
@@ -138,7 +138,7 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.Rea |
| 138 | 138 |
if err != nil {
|
| 139 | 139 |
return err |
| 140 | 140 |
} |
| 141 |
- req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.APIVERSION, path), params)
|
|
| 141 |
+ req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.Version, path), params)
|
|
| 142 | 142 |
if err != nil {
|
| 143 | 143 |
return err |
| 144 | 144 |
} |
| ... | ... |
@@ -53,7 +53,7 @@ func (cli *DockerCli) clientRequest(method, path string, in io.Reader, headers m |
| 53 | 53 |
if expectedPayload && in == nil {
|
| 54 | 54 |
in = bytes.NewReader([]byte{})
|
| 55 | 55 |
} |
| 56 |
- req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.APIVERSION, path), in)
|
|
| 56 |
+ req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.Version, path), in)
|
|
| 57 | 57 |
if err != nil {
|
| 58 | 58 |
return nil, nil, -1, err |
| 59 | 59 |
} |
| ... | ... |
@@ -26,7 +26,7 @@ func (cli *DockerCli) CmdVersion(args ...string) error {
|
| 26 | 26 |
if dockerversion.VERSION != "" {
|
| 27 | 27 |
fmt.Fprintf(cli.out, "Client version: %s\n", dockerversion.VERSION) |
| 28 | 28 |
} |
| 29 |
- fmt.Fprintf(cli.out, "Client API version: %s\n", api.APIVERSION) |
|
| 29 |
+ fmt.Fprintf(cli.out, "Client API version: %s\n", api.Version) |
|
| 30 | 30 |
fmt.Fprintf(cli.out, "Go version (client): %s\n", runtime.Version()) |
| 31 | 31 |
if dockerversion.GITCOMMIT != "" {
|
| 32 | 32 |
fmt.Fprintf(cli.out, "Git commit (client): %s\n", dockerversion.GITCOMMIT) |
| ... | ... |
@@ -16,8 +16,14 @@ import ( |
| 16 | 16 |
|
| 17 | 17 |
// Common constants for daemon and client. |
| 18 | 18 |
const ( |
| 19 |
- APIVERSION version.Version = "1.20" // Current REST API version |
|
| 20 |
- DefaultDockerfileName string = "Dockerfile" // Default filename with Docker commands, read by docker build |
|
| 19 |
+ // Current REST API version |
|
| 20 |
+ Version version.Version = "1.20" |
|
| 21 |
+ |
|
| 22 |
+ // Minimun REST API version supported |
|
| 23 |
+ MinVersion version.Version = "1.12" |
|
| 24 |
+ |
|
| 25 |
+ // Default filename with Docker commands, read by docker build |
|
| 26 |
+ DefaultDockerfileName string = "Dockerfile" |
|
| 21 | 27 |
) |
| 22 | 28 |
|
| 23 | 29 |
type ByPrivatePort []types.Port |
| ... | ... |
@@ -244,7 +244,7 @@ func (s *Server) postAuth(version version.Version, w http.ResponseWriter, r *htt |
| 244 | 244 |
func (s *Server) getVersion(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
| 245 | 245 |
v := &types.Version{
|
| 246 | 246 |
Version: dockerversion.VERSION, |
| 247 |
- ApiVersion: api.APIVERSION, |
|
| 247 |
+ ApiVersion: api.Version, |
|
| 248 | 248 |
GitCommit: dockerversion.GITCOMMIT, |
| 249 | 249 |
GoVersion: runtime.Version(), |
| 250 | 250 |
Os: runtime.GOOS, |
| ... | ... |
@@ -1477,14 +1477,18 @@ func makeHttpHandler(logging bool, localMethod string, localRoute string, handle |
| 1477 | 1477 |
} |
| 1478 | 1478 |
version := version.Version(mux.Vars(r)["version"]) |
| 1479 | 1479 |
if version == "" {
|
| 1480 |
- version = api.APIVERSION |
|
| 1480 |
+ version = api.Version |
|
| 1481 | 1481 |
} |
| 1482 | 1482 |
if corsHeaders != "" {
|
| 1483 | 1483 |
writeCorsHeaders(w, r, corsHeaders) |
| 1484 | 1484 |
} |
| 1485 | 1485 |
|
| 1486 |
- if version.GreaterThan(api.APIVERSION) {
|
|
| 1487 |
- http.Error(w, fmt.Errorf("client is newer than server (client API version: %s, server API version: %s)", version, api.APIVERSION).Error(), http.StatusBadRequest)
|
|
| 1486 |
+ if version.GreaterThan(api.Version) {
|
|
| 1487 |
+ http.Error(w, fmt.Errorf("client is newer than server (client API version: %s, server API version: %s)", version, api.Version).Error(), http.StatusBadRequest)
|
|
| 1488 |
+ return |
|
| 1489 |
+ } |
|
| 1490 |
+ if version.LessThan(api.MinVersion) {
|
|
| 1491 |
+ 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)
|
|
| 1488 | 1492 |
return |
| 1489 | 1493 |
} |
| 1490 | 1494 |
|
| ... | ... |
@@ -3,15 +3,18 @@ package main |
| 3 | 3 |
import ( |
| 4 | 4 |
"net/http" |
| 5 | 5 |
"net/http/httputil" |
| 6 |
+ "strconv" |
|
| 7 |
+ "strings" |
|
| 6 | 8 |
"time" |
| 7 | 9 |
|
| 10 |
+ "github.com/docker/docker/api" |
|
| 8 | 11 |
"github.com/go-check/check" |
| 9 | 12 |
) |
| 10 | 13 |
|
| 11 | 14 |
func (s *DockerSuite) TestApiOptionsRoute(c *check.C) {
|
| 12 | 15 |
status, _, err := sockRequest("OPTIONS", "/", nil)
|
| 13 |
- c.Assert(status, check.Equals, http.StatusOK) |
|
| 14 | 16 |
c.Assert(err, check.IsNil) |
| 17 |
+ c.Assert(status, check.Equals, http.StatusOK) |
|
| 15 | 18 |
} |
| 16 | 19 |
|
| 17 | 20 |
func (s *DockerSuite) TestApiGetEnabledCors(c *check.C) {
|
| ... | ... |
@@ -26,7 +29,7 @@ func (s *DockerSuite) TestApiGetEnabledCors(c *check.C) {
|
| 26 | 26 |
//c.Assert(res.Header.Get("Access-Control-Allow-Headers"), check.Equals, "Origin, X-Requested-With, Content-Type, Accept, X-Registry-Auth")
|
| 27 | 27 |
} |
| 28 | 28 |
|
| 29 |
-func (s *DockerSuite) TestVersionStatusCode(c *check.C) {
|
|
| 29 |
+func (s *DockerSuite) TestApiVersionStatusCode(c *check.C) {
|
|
| 30 | 30 |
conn, err := sockConn(time.Duration(10 * time.Second)) |
| 31 | 31 |
c.Assert(err, check.IsNil) |
| 32 | 32 |
|
| ... | ... |
@@ -40,3 +43,31 @@ func (s *DockerSuite) TestVersionStatusCode(c *check.C) {
|
| 40 | 40 |
res, err := client.Do(req) |
| 41 | 41 |
c.Assert(res.StatusCode, check.Equals, http.StatusBadRequest) |
| 42 | 42 |
} |
| 43 |
+ |
|
| 44 |
+func (s *DockerSuite) TestApiClientVersionNewerThanServer(c *check.C) {
|
|
| 45 |
+ v := strings.Split(string(api.Version), ".") |
|
| 46 |
+ vMinInt, err := strconv.Atoi(v[1]) |
|
| 47 |
+ c.Assert(err, check.IsNil) |
|
| 48 |
+ vMinInt++ |
|
| 49 |
+ v[1] = strconv.Itoa(vMinInt) |
|
| 50 |
+ version := strings.Join(v, ".") |
|
| 51 |
+ |
|
| 52 |
+ status, body, err := sockRequest("GET", "/v"+version+"/version", nil)
|
|
| 53 |
+ c.Assert(err, check.IsNil) |
|
| 54 |
+ c.Assert(status, check.Equals, http.StatusBadRequest) |
|
| 55 |
+ c.Assert(len(string(body)), check.Not(check.Equals), 0) // Expected not empty body |
|
| 56 |
+} |
|
| 57 |
+ |
|
| 58 |
+func (s *DockerSuite) TestApiClientVersionOldNotSupported(c *check.C) {
|
|
| 59 |
+ v := strings.Split(string(api.MinVersion), ".") |
|
| 60 |
+ vMinInt, err := strconv.Atoi(v[1]) |
|
| 61 |
+ c.Assert(err, check.IsNil) |
|
| 62 |
+ vMinInt-- |
|
| 63 |
+ v[1] = strconv.Itoa(vMinInt) |
|
| 64 |
+ version := strings.Join(v, ".") |
|
| 65 |
+ |
|
| 66 |
+ status, body, err := sockRequest("GET", "/v"+version+"/version", nil)
|
|
| 67 |
+ c.Assert(err, check.IsNil) |
|
| 68 |
+ c.Assert(status, check.Equals, http.StatusBadRequest) |
|
| 69 |
+ c.Assert(len(string(body)), check.Not(check.Equals), 0) // Expected not empty body |
|
| 70 |
+} |